간략하게 정의만 작성 ( 추후 예제도 추가 예정 )
직접 사용해보면서 알게 된 점도 적어둘 예정입니다.
@State는 상태를 나타내며, 이 상태가 변경되면 연결된 뷰를 다시 그린다.
따라서 변경된 값을 화면에 보여주어야 할 때 사용하며, 제일 많이 사용된다.
공식 사이트에도 잘 설명되어 있다.
@State는 이렇게 작성하면 된다. private는 상황에 맞게.. 필수는 아니다!
예시로 간단하게 버튼을 탭했을 때 count가 올라가는 코드를 작성하면..
이렇게 작성할 수 있다.
struct ContentView: View {
@State private var clickEvent = 1
var body: some View {
HStack {
Button(action: {
clickEvent += 1
}, label: {
Text("-")
})
.foregroundColor(.gray)
.frame(width: 30, height: 20, alignment: .center)
.overlay(
RoundedRectangle(cornerRadius: 0)
.stroke(.gray, lineWidth: 1)
)
Text(clickEvent.description)
.foregroundColor(.black)
.frame(width: 50, height: 30, alignment: .center)
.overlay(
RoundedRectangle(cornerRadius: 0)
.stroke(.black, lineWidth: 1)
)
.padding()
}.padding(.trailing, 20)
}
}
버튼을 누를때마다 1을 추가하고 해당 값을 텍스트로 출력하는 간단한 예제이다.
( 바인딩해서 하는 예제는 추후 바인딩 작성할 때 추가하도록 하겠습니다 )
..만약 @State를 제외하면.. 뷰 내부에서 demodata의 값을 변경하는 코드가 있다면 Cannot use mutating member on immutable value: 'self' is immutable 에러가 나게 될 것이다.
SwiftUI의 경우 뷰가 구조체로 이루어져있는데, 구조체의 경우 메소드 안의 값을 수정할 수 없기 때문에 값을 변경하게 된다면 에러가 나게된다.
때문에 @State를 이용하여 상태(값)이/가 변경되면 연결된 뷰를 다시 그리는 작업을 한다.
그럼 값을 수정할 수 있다. 위 예제처럼 말이다.
@Binding은 상위뷰의 @State를 하위뷰에 공유해야 할 때 하위뷰에서 사용한다.
사용할 때 $ 키워드를 사용한다.
전달"받을거면" @Binding, 전달"해줄거면" @State
@EnvironmentObject는 하위뷰에 모두 공유해야 할 때 사용한다.
공식문서에 따르면 하위뷰에 ObservableObject을 제공한다고..하는데 잘 모르겠다.
검색해보니 사용자 인터페이스 밖에 있으며 앱 내의 SwiftUI 뷰 구조체의 하위 뷰에만 필요한 데이터는 Observable 오브젝트를 이용하고, 사용자 인터페이스 밖에 있으며 여러 뷰에서 접근해야 하는 데이터는 Environment 오브젝트를 활용한다고한다.
음.. 상위뷰에 데이터가 여러개면 Binding이 아니고 Environment를 사용한다는 걸까?
( 해당 부분은 더 공부하고 추가하겠습니다 )
@propertyWrapper struct Published<Value>
@ObservableObject 프로토콜을 준수하는 것은 SwiftUI의 뷰들이 변경사항에 대해 관찰할 수 있다는 의미이다.
class Box: ObservableObject {
var item = [String]()
}
하지만 유일한 프로퍼티가 @Published로 표시되지 않았기 때문에, 변경사항 알림이 전송되지 않을 것이다. 해서 이 클래스는 배열에 항목들을 자유롭게 추가할 수 있지만 뷰들은 업데이트 하지않고있다.
item에 무언가 추가되거나 제거될때마다 변경사항 알림을 보내고자하는 경우, 다음과 같이 @Published로 표시한다.
class Box: ObservableObject {
@Published var item = [String]()
}
@Published property wrapper는 실제로 items에 willSet property observer를 추가하므로, 모든 변경사항은 자동으로 관찰자(observers)에게 전송된다.