만약 사용자가 버튼을 누르거나 스크롤을 하거나 텍스트에 상자를 입력했다고 치면, 그 특정 행동은 그 State 즉 상태를 변경한다. 그 이후에 일어날 일은 State가 변경되면 자동으로 변환시켜주는 일을 한다.
사용자 인터페이스를 업데이트하는 것이다.
그렇다면 어떻게 이렇게 할 수 있을까?
View를 사용할 때 ContentView가 실제로 View 프로토콜을 준수한다는 것을 기억해야한다. Body속성을 작성한다. 이것이 View 프로토콜의 유일한 요구 사항이다.
상태를 변경할 때마다 body속성이 재설정 된다. 뷰 자체가 다시 렌더링 되는 것.
따라서 State를 변경 할 때마다 항상 새로운 View에서 렌더링 된다는 점을 기억하자!
그리고 사용자가 그것을 보게 된다.
사용자가 스위치를 켜고 끄는 것처럼 상태를 변경할 때 그 값을 State안에 넣으면 뷰를 렌더링 하게 된다.
이것을 사용하기 위해서는 @State와 Struct를 필수적으로 사용해야 합니다. Strcut 내부의 값이 전체 Struct를 변경할 때마다 전체 구조체가 자동적으로 변경된다.
특정 view에서만 사용하는 프로퍼티
복잡한 프로퍼티(여러 프로퍼티나 메서드가 있거나 , 여러 view에서 공유할 수 있는 커스텀 타입이 있는 경우)
- String이나 integer 같은 간단한 로컬 프로퍼티 대신 외부 참조 타입을 사용한다는 점을 제외하면 @State와 매우 유사하다
- @ObservedObject와 함꼐 사용하는 타입은 ObservedObject 프로토콜을 따라야한다.
- @ObservedObject가 데이터가 변경되었음을 view에 알리는 방법은 여러가지가 있지만 가장 쉬운 방법은 @Published 프로퍼티 래퍼를 사용하는 것 - SwiftUI에 view reload를 트리거
class UserSettings: ObservableObject {
//@ObervedObjet를 사용하기위해 @Published를 할당
@Published var score = 0
}
struct ContentView: View {
//@state를 지우고 @ObervedObject로 바꿔줌
@ObservedObject var settings = UserSettings()
var body: some View {
VStack {
Text("나의 점수는 \(settings.score)점 입니다.")
Button(action: {
self.settings.score += 1
}) {
Text("Increase Score")
}
}
}
}
score에 @Published가 붙었기 때문에 이 score가 변경되면 view를 reload하게 된다.
@ObservedObject property wrapper는 ObservableObject프로토콜에 적합한 유형에만 사용할 수 있으며 실제로 해결하기도 쉽다.
FruitViewModel -> protocol : ObservableObject
FruitBasicView -> @ObservedObject
결과 화면
아토언니! 좋은 정보 잘 보고 가요~!