๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐ŸŽ iOS/SwiftUI

[SwiftUI] View ์—…๋ฐ์ดํŠธ ๋ฐฉ์‹ - @State, @Binding

์•ˆ๋…•ํ•˜์„ธ์š” ์ œ์ธ์ž…๋‹ˆ๋‹ค :) 

SwiftUI์—์„œ๋Š” ๋ทฐ๋ฅผ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•˜๋Š”์ง€ ์•Œ์•„๋ณด๊ณ , SwiftUI์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ๋‹ค์–‘ํ•œ ํ”„๋กœํผํ‹ฐ ๋ž˜ํผ ์ค‘ ๋Œ€ํ‘œ์ ์ธ ๋ช‡ ๊ฐ€์ง€์— ๋Œ€ํ•ด์„œ ์‚ดํŽด๋ณผ๊ฒŒ์š”~!

SwiftUI์˜ View ์—…๋ฐ์ดํŠธ ๋ฐฉ์‹

SwiftUI์—์„œ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ์ด์— ๋”ฐ๋ผ ๋ทฐ๊ฐ€ ๋ฐ”๋€๋‹ˆ๋‹ค. ์ฆ‰, ๋ทฐ๋Š” ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์˜์กด์„ฑ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

SwiftUI์—์„œ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ทฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ๋‚ด๋ถ€์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ ์‹œ์ ์„ ๊ณ„์‚ฐํ•ด์„œ ๋ทฐ๋ฅผ ์—…๋ฐ์ดํŠธ ์‹œ์ผœ์ฃผ๋Š” ์ผ์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ผ์ผ์ด ํ•ด์ฃผ์ง€ ์•Š์•„๋„ ๋˜๋Š” ๊ฒƒ์ด์ฃ . ์ด๋ฅผ ์œ„ํ•ด SwiftUI์—์„œ๋Š” ๋‹ค์–‘ํ•œ ํ”„๋กœํผํ‹ฐ ๋ž˜ํผ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ์ค‘ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ @State, @Binding ์„ ์ด์šฉํ•ด ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ๋ทฐ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ธ์ง€ ์ •๋ฆฌํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@State

  • ์˜๊ตฌ์ ์ธ ์ €์žฅ์†Œ๋ฅผ ์ƒ์„ฑ (Single Source of Truth)
  • ๋ทฐ์— ๋Œ€ํ•œ ์˜์กด์„ฑ ์ถ”์ 
  • ๊ฐ’์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š” ๋ทฐ ๊ณ„์ธต์˜ ๋ถ€๋ถ„๋งŒ ์—…๋ฐ์ดํŠธ (ํšจ์œจ์ ์ธ ์—…๋ฐ์ดํŠธ)
  • state๋กœ ์ •์˜๋œ ํ”„๋กœํผํ‹ฐ๋ฅผ ํ•˜์œ„ ๋ทฐ์— ์ „๋‹ฌํ•˜๋ฉด ๊ฐ’ ๋ณ€๊ฒฝ ๋  ๋•Œ๋งˆ๋‹ค ํ•˜์œ„ ๋ทฐ๊นŒ์ง€ ์—…๋ฐ์ดํŠธ ๋จ. but ํ•˜์œ„ ๋ทฐ์—์„œ ๊ฐ’์„ ์ˆ˜์ •ํ•  ์ˆ˜๋Š” ์—†๋‹ค! (ํ•˜์œ„ ๋ทฐ๊นŒ์ง€ ์—ฐ๊ฒฐํ•˜๋ ค๋ฉด @Binding์„ ์ „๋‹ฌํ•ด์•ผ ํ•จ)

๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์— ๋”ฐ๋ฅธ ๋ทฐ ์—…๋ฐ์ดํŠธ ๊ณผ์ •

@State ํ”„๋กœํผํ‹ฐ์— ์ €์žฅ๋˜๋Š” ๊ฐ’์˜ ๋ณ€๊ฒฝ์— ๋”ฐ๋ผ ๋ทฐ๊ฐ€ ๊ฐฑ์‹ ๋˜๋Š” ๊ณผ์ •์„ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ ์ฝ”๋“œ์™€ ๊ทธ๋ฆผ์œผ๋กœ ์ดํ•ดํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

 

struct PlayButton: View {
    @State private var isPlaying: Bool = false // Create the state.


    var body: some View {
        Button(isPlaying ? "Pause" : "Play") { // Read the state.
            isPlaying.toggle() // Write the state.
        }
    }
}

 

์œ„์˜ ์ฝ”๋“œ๋Š” ๊ณต์‹๋ฌธ์„œ์— ๋‚˜์™€์žˆ๋Š” ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋ฆฐ๋ฐ์š”, ๋ทฐ์˜ body ๋‚ด์—์„œ ๋ฒ„ํŠผ์œผ๋กœ state๋กœ ์„ ์–ธ๋œ isPlaying ์ด๋ผ๋Š” ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. isPlaying ๊ฐ’(= ๋ฐ์ดํ„ฐ)์ด ๋ณ€ํ•˜๋ฉด ์ด์— ๋”ฐ๋ผ Button ํƒ€์ดํ‹€ UI(= ๋ทฐ)๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š”๋ฐ์š”, ์–ด๋–ค ๊ณผ์ •์œผ๋กœ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•ด์„œ ๋ทฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์ค„ ์ˆ˜ ์žˆ๋Š”์ง€ ๊ทธ๋ฆผ์œผ๋กœ ์‚ดํŽด๋ณผ๊ฒŒ์š”!

 

1. @State๋กœ ์„ ์–ธ๋œ ํ”„๋กœํผํ‹ฐ์˜ ์˜๊ตฌ์ ์ธ ์ €์žฅ์†Œ ํ• ๋‹น

๋จผ์ €, SwiftUI๋Š” @State๋กœ ์„ ์–ธ๋œ ํ”„๋กœํผํ‹ฐ์˜ ์˜๊ตฌ์ ์ธ ์ €์žฅ์†Œ๋ฅผ ํ• ๋‹นํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด, ์ด์ œ ๋ทฐ ๋ Œ๋”๋ง์ด ํ•ด๋‹น ๊ฐ’์— ์˜์กดํ•˜๊ฒŒ ๋œ๋‹ค๋Š” ๊ฒƒ์„ ๋‚ด๋ถ€์ ์œผ๋กœ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

2. ํ”„๋กœํผํ‹ฐ ๋ณ€๊ฒฝ ํ›„ ๊ด€๋ จ ๋ทฐ๋“ค์˜ ์žฌ์ƒ์„ฑ 

์œ„์˜ ์ฝ”๋“œ์—์„œ, ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด isPlaying ๊ฐ’์ด ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด, ํ•ด๋‹น ์ƒํƒœ์— ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ๋ทฐ์˜ body๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ทฐ๋ฅผ ์žฌ์ƒ์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ, ๋ทฐ ์ „์ฒด๋ฅผ ์žฌ์ƒ์„ฑํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ๋ทฐ ๊ณ„์ธต๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ผ ๋‚ด๋ ค๊ฐ€๋ฉด์„œ ๊ฐฑ์‹ ์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๊ฒ€์‚ฌํ•ด์„œ ํ•ด๋‹น ๋ถ€๋ถ„๋งŒ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

@Binding

์œ„์—์„œ @State๋ฅผ ์ด์šฉํ•˜๋ฉด ํ•˜์œ„ ๋ทฐ์—์„œ ๊ฐ’์„ ์ˆ˜์ •ํ•  ์ˆ˜๋Š” ์—†๋‹ค๊ณ  ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ, ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด ๋ทฐ ๊ณ„์ธต์„ ๋‚˜๋ˆ ์•ผ ํ•  ์ผ์ด ์ƒ๊ธฐ๊ฒŒ ๋˜์ฃ ? ์ด ๋•Œ, ํ•˜์œ„ ๋ทฐ๊นŒ์ง€ ์—ฐ๊ฒฐ์„ ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด @Binding์„ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.

 

  • ์ƒ์œ„ ๋ทฐ์™€ ํ•˜์œ„ ๋ทฐ ์‚ฌ์ด์— ์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ์„ ๋งŒ๋“ฆ
  • ๊ฐ’์„ ์ง์ ‘ ์ €์žฅํ•˜๋Š” ๋Œ€์‹ , ๊ฐ’์˜ ์ฐธ์กฐ๋ฅผ ์ €์žฅ
  • ์ฆ‰, @Binding ์„ ์‚ฌ์šฉํ•ด ์ƒ์œ„ ๋ทฐ์˜ ์†์„ฑ์— ์—ฐ๊ฒฐ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ
  • ํ•˜์œ„ ๋ทฐ๋„ ๋™์ผํ•œ ์†Œ์Šค๋ฅผ ๋ฐ”๋ผ๋ณด๋ฉฐ ์ฝ๊ธฐ/์“ฐ๊ธฐ ๋ชจ๋‘ ๊ฐ€๋Šฅํ•ด์ง
  • state ํ”„๋กœํผํ‹ฐ์—์„œ projectedValue๋ฅผ ํ†ตํ•ด binding ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด ๊ฐ’์€ $property๋ช… ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅ

์œ„์—์„œ ๋ดค๋˜ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด PlayButton ๊ตฌ์กฐ์ฒด๋ฅผ PlayView ๊ตฌ์กฐ์ฒด์˜ ํ•˜์œ„ ๋ทฐ๋กœ ๋งŒ๋“ค๊ณ , @Binding์„ ์ด์šฉํ•ด ์—ฐ๊ฒฐํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

struct PlayButton: View {
    @Binding var isPlaying: Bool // Play button now receives a binding.


    var body: some View {
        Button(isPlaying ? "Pause" : "Play") {
            isPlaying.toggle()
        }
    }
}

๋จผ์ €, @State๋กœ ์ •์˜๋˜์–ด ์žˆ๋˜ isPlaying์„ @Binding์œผ๋กœ ์ •์˜ํ•ด์ค๋‹ˆ๋‹ค.

 

struct PlayerView: View {
    @State private var isPlaying: Bool = false // Create the state here now.


    var body: some View {
        VStack {
            PlayButton(isPlaying: $isPlaying) // Pass a binding.


            // ...
        }
    }
}

๊ทธ๋Ÿฐ ๋‹ค์Œ, PlayButton์˜ ์ƒ์œ„ ๋ทฐ์ธ PlayerView๋ฅผ ๋งŒ๋“ค๊ณ , ์ด ์ƒ์œ„ ๋ทฐ์—์„œ isPlaying์„ @State๋กœ ์ •์˜ํ•ด์ค๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์ƒ์œ„ ๋ทฐ์—์„œ ์‹œ์ž‘๋˜๋Š” ํ•˜๋‚˜์˜ ์ €์žฅ์†Œ๊ฐ€ ์ƒ๊ธด ๊ฒƒ์ด๊ณ , ์ด์— ์—ฐ๊ฒฐ๋˜๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ด Single truth of Source๋ฅผ ๋ฐ”๋ผ๋ณด๊ณ  ์žˆ๋Š” ๊ฒƒ์œผ๋กœ, @Binding์œผ๋กœ ์—ฐ๊ฒฐ๋œ ํ•˜์œ„ ๋ทฐ์˜ ์†์„ฑ๋“ค์€ ๋ชจ๋‘ ์ด state ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด ์ฝ๊ธฐ/์“ฐ๊ธฐ๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์ฝ”๋“œ๋ฅผ ์ž์„ธํžˆ ๋ณด๋ฉด, PlayerView๋Š” isPlaying ์ด๋ผ๋Š” state ๊ฐ’์„ ๋™์ผํ•œ ์ด๋ฆ„์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ($๋ถ™์—ฌ์„œ ๊ฐ’์„ ์ „๋‹ฌ)

ํ•˜์œ„ ๋ทฐ์ธ PlayButton์—์„œ๋Š” isPlaying ์ด๋ผ๋Š” ๋ฐ”์ธ๋”ฉ ๊ฐ’์„ ์‚ฌ์šฉํ•ด ์ƒ์œ„ ๋ทฐ์˜ isPlaying ๊ฐ’์„ ์ฝ๊ณ  ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

 

 

SwiftUI๋กœ ๊ฐœ๋ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ์•„์ฃผ ๊ธฐ๋ณธ์ ์ธ ๋‚ด์šฉ์ธ๋ฐ, ์ด๋ ‡๊ฒŒ ๊ทธ๋ฆผ์„ ์ด์šฉํ•ด ์„ค๋ช…ํ•ด๋ณด๋‹ˆ ๋” ํ™•์‹คํ•˜๊ฒŒ ์ •๋ฆฌ๊ฐ€ ๋˜๋Š” ๊ฒƒ ๊ฐ™๋„ค์š”๐Ÿ˜Š

SwiftUI์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” State ๊ด€๋ จ ํ”„๋กœํผํ‹ฐ ๋ž˜ํผ๊ฐ€ ๊ต‰์žฅํžˆ ๋งŽ์€๋ฐ, ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ๋งŽ์ด ์‚ฌ์šฉํ–ˆ์—ˆ๋˜ ํ”„๋กœํผํ‹ฐ ๋ž˜ํผ์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ๊ฒŒ์‹œ๊ธ€์—์„œ ๋” ์ •๋ฆฌํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

๊ธด ๊ธ€ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค๐Ÿ˜Š


[์ฐธ๊ณ  ์ž๋ฃŒ]

 

State | Apple Developer Documentation

A property wrapper type that can read and write a value managed by SwiftUI.

developer.apple.com

 

SwiftUI @State์™€ @Binding ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž

@State @State๋Š” SwiftUI์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์†์„ฑ ๋ž˜ํผ(Wrapper)๋กœ, ๊ฐ’์˜ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜๊ณ  ๋ทฐ๋ฅผ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. @State๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด ํ•ด๋‹น ๊ฐ’์— ์˜์กดํ•˜๋Š” ๋ทฐ๊ฐ€ ์ž๋™์œผ๋กœ

develop-const.tistory.com

'๐ŸŽ iOS > SwiftUI' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[SwiftUI] View Life Cycle  (0) 2024.08.19