@State
- SwiftUI는 state로 선언한 모든 프로퍼티의 스토리지를 관리
- @State를 앞에 추가하면 SwiftUI가 자동으로 변경사항을 observe하고 해당 state를 사용하는 view부분을 업데이트
- view 인스턴스를 만들면서 해당 view의 state 프로퍼티는 초기화하면 프로퍼티를 관리하는 swiftui와 충돌이 발생할수 있으므로, 항상 state프로퍼티를 private으로 선언
@Binding
// 부모 view
struct PlayerView: View {
var episode: Episode
@State private var isPlaying: Bool = false
var body: some View {
VStack {
Text(episode.title)
.foregroundStyle(isPlaying ? .primary : .secondary)
PlayButton(isPlaying: $isPlaying) // Pass a binding.
}
}
}
// 자식 view
struct PlayButton: View {
@Binding var isPlaying: Bool
var body: some View {
Button(isPlaying ? "Pause" : "Play") {
isPlaying.toggle()
}
}
}
- 부모 view의 state 프로퍼티를 자식 view와 양방향연결(read,write)을 할때 사용
- 자식 view는 @State대신 @Binding으로 받으며, 부모 view는 프로퍼티앞에 $을 붙임으로써 바인딩을 전달
@ObservedObject
class UserProgress: ObservableObject {
@Published var score = 0
}
// 부모 view
struct ContentView: View {
@StateObject var progress = UserProgress()
var body: some View {
VStack {
Text("Your score is \(progress.score)")
InnerView(progress: progress)
}
}
}
// 자식 view
struct InnerView: View {
@ObservedObject var progress: UserProgress
var body: some View {
Button("Increase Score") {
progress.score += 1
}
}
}
- 여러 프로퍼티나 메소드가 있는 객체 처럼 복잡한 프로퍼티인 경우 @State 대신 @ObservedObject를 사용
- swiftui는 ObservableObject 프로토콜을 준수하는 객체 내부에 @Published가 붙은 프로퍼티가 변경되면 SwiftUI에 view reload를 트리거
- ObservableObject 프로토콜을 준수하는 객체의 인스턴스를 생성하기 위해서는 @ObservedObject가 아닌 @StateObject를 사용해야 한다
@EnvironmentObject
// ObservableObject
class Info: ObservableObject {
@Published var age = 10
}
//
class SceneDelegate {
...
var info = Info()
window.rootViewController = UIHostingController(rootView: ContentView()
.environmentObject(info))
...
}
// subview 1
struct MainView: View {
@EnvironmentObject var info: Info
var body: some View {
Button(action: {
self.info.age += 1
}) {
Text("Click Me for plus age")
}
SubView()
}
}
// subview 2
struct SubView: View {
@EnvironmentObject var info: Info
var body: some View {
Button(action: {
self.info.age -= 1
}) {
Text("Click Me for minus age")
}
}
}
- 앱의 여러 뷰에서 공용되는 ObservableObject 객체는 @EnvironmentObject를 사용
- 필요한 곳 어디에서든 데이터를 공유하고 데이터가 변경 될 때 뷰가 자동으로 업데이튼 된 상태로 유지할 수 있다.
- 전역적 사용을 위해 SceneDelegate에서 contentView.environmentObject(_:) 메서드를 통해 ObservableObject를 하위뷰들에게 전달하고 이를 사용할 뷰들에서 프로퍼티로 @EnvironmentObject 어노테이션을 붙인 변수를 생성
참고
https://seons-dev.tistory.com/35
https://developer.apple.com/documentation/swiftui/binding
https://developer.apple.com/documentation/swiftui/state
https://green1229.tistory.com/229
https://zeddios.tistory.com/964?category=796110
'iOS 🍎 > SwiftUI' 카테고리의 다른 글
ViewBuilder (0) | 2022.11.10 |
---|