Making classes observable
@State, @Binding속성 래퍼는 값 타입에서만 사용이 가능하며 두 속성 래퍼는 뷰 계층 구조에서 업데이트를 수행 합니다
이번엔 참조 유형을 다루는 방법에 대해서 알아 볼 수 있습니다
Working with reference types
이전에 배웠던 @State속성을 추가해서 프로퍼티를 식별했지만 구조체와 열거형 같은 값 유형에 대해서만 사용이 가능합니다
SwiftUI는 참조 유형을 Source of of truth로 선언할 수 있는 프로퍼티 래퍼를 제공하고 있습니다 :@ObservedObject, @StateObject, @EnvironmentObject
클래스에서 위에서 제시한 프로퍼티 래퍼를 사용하려면 클래스 Observable(관찰가능)하게 만들 필요가 있습니다
Making a class observable
클래스를 관찰 가능하게 하려면 ObservableObject 프로토콜을 채택하면 됩니다
클래스에서 변경 시에 UI Update를 트리거할 때 프로퍼티를 인식합니다
그다음 각 속성안에 @Published 속성을 추가합니다
class ScrumTimer: ObservableObject {
@Published var activeSpeaker = ""
@Published var secondsElapsed = 0
@Published var secondsRemaining = 0
// ...
}
이 클래스는 스크럼 세션동안 업데이트되는 여러개의 @published 속성을 정의하고 있습니다
스크럼타이머는 값이 변경되므로 모든 관찰자에게 알릴 수 있습니다
Monitoring an object for changes
프로퍼티 선언에 다음 속성중 하나를 추가하여 SwiftUI에서 관찰 가능한 객체를 모니터링 할 수 있습니다
ObservedObject, StateObject,EnvironmentObject 래퍼 중 하나 사용하여 선언된 뷰 속성은 뷰 계층 구조에 대한 새로운 데이터 소스를 만들게 됩니다
@StateObject 래퍼를 사용하면 관찰가능한 오브젝트를 생성할 수 있습니다
앱, 씬, 뷰안에서 state object를 생성할 수 있습니다
이 시스템이 객체 초기화하면 해당 구조나 다른 뷰에서 사용할 수 있도록 개체를 유지하게 됩니다
struct MeetingView: View {
@StateObject var scrumTimer = ScrumTimer()
// ...
}
App, Scene, View와 같은 상위 소스에서 뷰가 개체를 전달받았음을 나타내려면 @ObservedObject 속성 래퍼를 사용합니다
이러한 상위구조는 개체를 만들고 소유하기 때문에 하위 뷰에서는 ObservedObject의 초기값이 필요없습니다
struct ChildView: View {
@ObservedObject var timer: ScrumTimer
// ...
}
관찰 가능한 객체의 인스턴스를 View의 초기화 할 때 넘겨줍니다
struct MeetingView: View {
@StateObject var scrumTimer = ScrumTimer()
var body: some View {
VStack {
ChildView(timer: scrumTimer)
}
}
// ...
}
복잡한 보기 계층 구조에서 관찰 가능한 개체를 공유하려면 @EnvironmentObject 속성 래퍼를 사용합니다
이니셜라이저를 통해 개체를 전달하는 대신 environment에 배치합니다
environmentObject(_:) 뷰 수정자는 뷰의 environmentObject를 배치합니다
struct ParentView: View {
@StateObject var scrumTimer = ScrumTimer()
var body: some View {
VStack {
ChildView()
.environmentObject(scrumTimer)
}
}
// ...
}
struct ChildView: View {
var body: some View {
GrandchildView()
}
}
계층 구조의 중간 뷰에 객체에 대한 참조가 없더라도 @EnvironmentObject 속성 래퍼를 사용하여 모든 하위 객체에 있는 객체에 액세스 할 수 있습니다
struct GrandchildView: View {
@EnvironmentObject var timer: ScrumTimer
// ...
}
@EnvironmentObject는 중간 뷰에서 불필요한 종속성을 만들지 않도록 할 수 있고 GrandParent/Parent 뷰는 모두 스크럼 타이머에 종속되고 있지만 자식 뷰에서는 그렇지 않는걸 볼 수 있습니다
'SwiftUI' 카테고리의 다른 글
SwiftUI | Examining data flow in Scrumdinger (0) | 2024.08.06 |
---|---|
SwiftUI | Adopting new API features (0) | 2024.08.06 |
Adopting Swift concurrency (0) | 2024.08.05 |
SwiftUI | Responding to events (0) | 2024.08.02 |
SwiftUI | Managing data flow between views(@State, @Binding) (0) | 2024.08.01 |