swift

SwiftUI @State와 @Binding 에 대해 알아보자

호리둥절 2023. 5. 17. 15:35

@State

@State는 SwiftUI에서 사용되는 속성 래퍼(Wrapper)로, 값의 변경을 감지하고 뷰를 자동으로 업데이트하는 데에 사용됩니다.

@State를 사용하면 값이 변경되면 해당 값에 의존하는 뷰가 자동으로 다시 렌더링되어 화면이 업데이트됩니다.

 

[ 예시코드 ]

struct ContentView: View {
    @State private var count = 0
    
    var body: some View {
        VStack {
            Text("Count: \(count)")
                .font(.title)
            
            Button(action: {
                count += 1
            }) {
                Text("Increment")
                    .font(.headline)
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
        }
    }
}
  • @State 속성 래퍼를 사용할 변수를 선언합니다. 예를 들어, @State private var count = 0와 같이 선언할 수 있습니다. 여기서 count는 상태 속성이며 초기값으로 0을 갖습니다. 
  • 상태 속성을 업데이트할 때는 일반적인 변수처럼 사용하면 됩니다. 예를 들어, Button(action: { count += 1 }) { Text("Increment") }와 같이 버튼을 클릭하면 count가 1씩 증가합니다.
  • @State 속성은 주로 View 구조체 내에서 사용됩니다. 뷰의 상태를 유지하고 해당 상태에 따라 뷰를 업데이트하는 데 사용됩니다.

 

 

@Binding

@Binding은 SwiftUI에서 데이터의 양방향 바인딩을 구현하기 위해 사용되는 속성 래퍼입니다. @Binding뷰 간에 데이터를 공유하고 업데이트하는 데 사용됩니다.

 

[ 특징 ] 

  • 값의 참조: @Binding 속성은 값 자체를 저장하는 것이 아니라, 값의 참조를 저장합니다. 따라서 부모 뷰와 자식 뷰가 같은 데이터 값을 참조하게 됩니다. 값이 변경되면 참조를 통해 모든 연결된 뷰에서 변경 내용이 반영됩니다.
  • 양방향 데이터 흐름: @Binding 속성은 값을 읽기만 하는 것이 아니라, 값을 수정할 수도 있습니다. 자식 뷰에서 값을 변경하면, 해당 변경 사항이 부모 뷰로 전파되어 다른 연결된 뷰에도 영향을 미칩니다. 이렇게 함으로써 부모 뷰와 자식 뷰 간의 양방향 데이터 흐름을 구현할 수 있습니다.
  • 데이터의 싱크: @Binding 속성은 데이터의 싱크(sync)를 자동으로 관리합니다. 부모 뷰에서 값을 업데이트하면 자식 뷰의 @Binding 속성도 함께 업데이트되어 동일한 값을 유지합니다. 마찬가지로, 자식 뷰에서 값을 변경하면 부모 뷰의 @Binding 속성도 동기화되어 변경된 값으로 업데이트됩니다.
  • 데이터 공유: @Binding 속성은 데이터를 여러 뷰 간에 공유할 수 있도록 해줍니다. 한 @Binding 속성을 여러 뷰에서 사용하면, 해당 데이터에 대한 변경 사항은 모든 연결된 뷰에 동시에 반영됩니다.

 

[ 예시코드 ]

struct ParentView: View {
    @State private var toggleState = false
    
    var body: some View {
        VStack {
            ChildView(isToggled: $toggleState)
            
            Text("Parent View Toggle State: \(toggleState.description)")
                .padding()
        }
    }
}

struct ChildView: View {
    @Binding var isToggled: Bool
    
    var body: some View {
        Toggle(isOn: $isToggled) {
            Text("Toggle")
        }
        .padding()
    }
}

위의 코드에서 ParentView는 toggleState라는 @State 속성을 가지고 있습니다. 이 값을 ChildView의 isToggled 매개변수에 $toggleState 바인딩으로 전달합니다. ChildView에서 Toggle의 isOn 매개변수는 isToggled 바인딩을 사용하여 ParentView의 toggleState 값을 읽고 업데이트합니다.

 

즉 ChildView isToggled 가 바뀌면 ParentView의 Text("Parent View Toggle State: \(toggleState.description)") 값도 바뀝니다.

 

이렇게 @Binding을 사용하면 부모 뷰와 자식 뷰 간에 데이터를 공유하고 업데이트할 수 있습니다. 자식 뷰에서 변경된 값은 @Binding 속성을 통해 부모 뷰로 다시 전달되어 전체 뷰 계층 구조가 동기화됩니다.