상태 프로퍼티는 상태에 대한 가장 기본적인 형태이며 즉 뷰 레이아웃의 현재 상태를 저장 하기 위해 서만 사용한다.
상태 프로퍼티는 String, Int 값처럼 간단한 데이터 타입을 저장하기 위해 사용된다.
@State 프로퍼티 래퍼를 사용하여 선언된다.상태 값은 해당 뷰에 속한 것이기 때문에 private 접근 제어자로 선언되어야 한다. -> 오류는 안난다.
상태 프로퍼티를 선언했다면 레이아웃에 있는 뷰와 바인딩을(bind)를 할 수 있다. 바인딩이 되어 있는 뷰에서 어떤 변경이 일어나면 해당 상태 프로퍼티에 자동으로 반영된다.
상태 프로퍼티에 변화가 생길 때마다 뷰 계층 구조는 SwiftUI에 의해 다시 렌더링 된다.
publisher), 구독자(subscriber)를 구축하여 할 수 있다.Observable 객체, State 객체, Environment 객체를 제공하여 사용자 인터페이스의 모양과 동작을 결정하는 상태를 제공한다.Binding 프로퍼티 래퍼를 사용하여 접근 해야한다.Binding 프로퍼티를 하위 뷰에 선언하여 전달 하면 된다.Swift, RxSwift 보다 매력적이라 생각이 드는 것이 Swift에서는 하위 뷰에 대한 데이터 전달이 매우 까다롭고 이미 하위 뷰인스턴스를 생성 해놓았기 때문에 바인딩 하기 어렵다 하지만 Binding 프로퍼티를 통해 데이터 바인팅 하기 쉽다는 것을 느꼈다.State)는 일시 적인 것이어서 부모 뷰가 사라지면 그 상태도 사라진다. 반면 Observable 객체는 여러 다른 뷰들이 외부에서 접근 할 수 있는 지속적인 데이터를 표현하기 위해 사용한다.Observable 객체는 ObservableObject 프로토콜을 따르는 클래스나 구조체 형태를 취하고 있으며 타이머나 알림(notification) 과 같은 이벤트를 처리하기 위해 사용될 수 있다.Observable 객체는 게시된 프로퍼티(published property) 로서 데이터 값을 게시하며 Observer 객체는 게시자를 구독(subscribe) 하여 게시된 프로퍼티가 변경 될때마다 업데이트를 받는다.Observable 객체의 게시된 프로퍼티를 구현하는 가장 쉬운 방법은 프로퍼티를 선언할때 Published 프로퍼티 래퍼를 사용하는 것이다.Publshed 래퍼는 프로퍼티 값이 변경될때마다 모든 구독자에게 업데이트를 알리게 된다.State Object) 프로퍼티 래퍼(StateObject) 는 ObservableObject래퍼의 대안 이다.ObservableObject를 쓰는 것은 안전하지 않다. ObjectObservable 객체를 외부에서 주입하는 것이 아니라면 StateObject 사용하는 것이 화면에 다시 그려져도 항상 같은 결과를 얻을 수 있다.Published를 통해 상태값을 관찰StateObject를 통해 변경된 상태값을 구독(바인딩) 처리final class CounterViewModel: ObservableObject {
@Published var count = 0
func incrementCounter() {
count += 1
}
}
final class MinusViewModel: ObservableObject {
private(set) var count = 0
func decrementCounter() {
count -= 1
objectWillChange.send()
}
}
struct StateNumberView: View {
@State var randNumber = 0
var body: some View {
VStack {
Text("Random number is \(randNumber)")
Button("Random Button") {
randNumber = (0...100).randomElement()!
}
}.padding()
ContentView()
}
}
struct ContentView: View {
@StateObject var viewModel: CounterViewModel = CounterViewModel()
var body: some View {
VStack {
Text("count is \(viewModel.count)")
Button("Increment Button") {
viewModel.incrementCounter()
}
}
}
}
navigation)하는 데 이동될 뷰에서도 동일한 구독 객체에 접근해야 한다면, 이동할 때 대상 뷰로 구독되는 객체에 대한 참조를 전달 해야 할 것이다.Environment객체는 Observable 객체와 같은 방식으로 선언되며 반드시 ObservableObject 프로토콜을 따라야 하며, 적절한 프로퍼티가 게시되어야 한다.