Coaspe

Making classes observable 본문

카테고리 없음

Making classes observable

Coaspe 2023. 8. 15. 22:26

@State 및 @Binding 프로퍼티 래퍼를 사용하여 뷰 계층에서 업데이트를 트리거하기 위한 source of truth로 값 유형을 정의했습니다. 이 문서에서는 앱의 사용자 인터페이스에 대한 source of truth로 참조 유형을 정의하는 방법에 대해 알아봅니다.

 

Working with reference types

@State 프로퍼티 래퍼는 구조 및 열거와 같은 값 유형에 대해서만 작동합니다. SwiftUI는 참조 유형을 source of truth로 선언하는 프로퍼티 래퍼를 제공합니다. @ObservedObject, @StateObject 및 @EnvironmentObject. 이러한 프로퍼티 래퍼를 클래스와 함께 사용하려면 클래스를 관찰 가능하게 만들어야 합니다.

 

Making a class observable

ObservableObject 프로토콜을 사용하여 클래스를 관찰 가능하게 만들 수 있습니다. 클래스에서 변경 시 UI 업데이트를 트리거해야 하는 속성을 식별한 다음 각 프로퍼티 선언에 @Published를 추가합니다.

class ScrumTimer: ObservableObject {
   @Published var activeSpeaker = ""
   @Published var secondsElapsed = 0
   @Published var secondsRemaining = 0
   // ...
}

위 클래스는 스크럼 세션 동안 업데이트되는 여러 publish된 속성을 선언합니다. 스크럼타이머는 publish된 속성의 값이 변경되면 관찰자에게 알립니다.

 

Monitoring an object for changes

프로퍼티 선언에 ObservedObject, StateObject, EnvironmentObject 중 하나를 추가하여 관찰 가능한 개체를 모니터링하도록 SwiftUI에 지시할 수 있습니다. 이러한 래퍼 중 하나로 선언된 뷰 프로퍼티은 뷰 계층에 대한 새로운 source of truth를 만듭니다.

@StateObject 래퍼를 사용하여 관찰 가능한 개체를 만듭니다. App, Scene, 또는 View 에서 상태 개체를 만들 수 있습니다.

시스템이 개체를 초기화하고 해당 구조 또는 개체를 전달하는 다른 뷰에서 개체를 사용할 수 있도록 유지합니다.

struct MeetingView: View {
   @StateObject var scrumTimer = ScrumTimer()
   // ...
}

@ObservedObject 속성 래퍼를 사용하여 뷰가 App, Scene 또는 View와 같은 상위 원본에서 개체를 받아왔음을 나타냅니다. 이 상위 구조는 개체를 생성하고 소유하므로 하위 뷰에는 ObservedObject에 대한 초기 값이 필요하지 않습니다:

struct ChildView: View {
   @ObservedObject var timer: ScrumTimer
   // ...
}

그런 다음 뷰의 이니셜라이저로 관찰 가능한 개체의 인스턴스를 넘겨줍니다.

struct MeetingView: View {
   @StateObject var scrumTimer = ScrumTimer()
   var body: some View {
      VStack {
         ChildView(timer: scrumTimer)
      }
   }
   // ...
}

@EnvironmentObject 속성 래퍼를 사용하여 복잡한 뷰 계층에서 관찰 가능한 개체를 공유합니다. 개체를 이니셜라이저에 전달하는 대신 개체를 환경에 배치합니다. environmentObject(_:) view modifier는 개체를 뷰의 환경에 배치합니다.

struct ParentView: View {
   @StateObject var scrumTimer = ScrumTimer()
   var body: some View {
      VStack {
         ChildView()
            .environmentObject(scrumTimer)
      }
   }
   // ...
}


struct ChildView: View {
    var body: some View {
        GrandchildView()
    }
}

그런 다음 계층의 중간 뷰에 개체에 대한 참조가 없더라도 @EnvironmentObject 속성 래퍼를 사용하여 ChildView의 자손이 개체에 액세스할 수 있습니다.

struct GrandchildView: View {
   @EnvironmentObject var timer: ScrumTimer
   // ...
}

@EnvironmentObject는 이러한 중간 뷰에서 불필요한 종속성을 생성하지 않도록 도와줍니다. ParentView와 HrandchildView는 ScrumTimer에 의존하지만 ChildView는 그렇지 않습니다.

Comments