PreferenceKey는 하위 뷰에서 상위 뷰로 데이터를 전달하기 위한 메커니즘입니다. 일반적으로 SwiftUI는 데이터가 상위 뷰에서 하위 뷰로 전달되는 구조를 따르지만, PreferenceKey는 그 반대 흐름을 가능하게 해줍니다.
PreferenceKey의 주요 구성 요소
PreferenceKey는 다음과 같이 세 가지 주요 요소로 이루어집니다:
- 키 등록: PreferenceKey 프로토콜 준수 및 타입 정의
- 값 송신: 하위 뷰에서 preference 메소드를 통해 값 전달
- 값 수신: 상위 뷰에서 onPreferenceChange 메소드를 통해 값 수신
PreferenceKey 프로토콜 구조
SwiftUI에서 PreferenceKey는 아래와 같은 프로토콜로 정의됩니다.
public protocol PreferenceKey {
associatedtype Value static
var defaultValue: Self.Value { get } // 기본 값 정의
static func reduce(value: inout Self.Value, nextValue: () -> Self.Value) // 값 병합 로직 }
- defaultValue: 값이 설정되지 않았을 때 사용할 기본값.
- reduce: 다중 값이 전달될 경우 병합할 방법을 정의.
뷰에서는 preference이름의 메서드가 존재한다. K는 PreferenceKey를 채택하고 있어 위에서 만든 type, value를 넣으면 해당 값을 관찰한다는 뜻이다. 또한 이 preference값이 변할때에 실행될 동작을 추가할 수도 있다.(두번째 method)
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension View {
@inlinable public func preference<K>(key: K.Type = K.self, value: K.Value) -> some View where K : PreferenceKey
@inlinable public func onPreferenceChange<K>(_ key: K.Type = K.self, perform action: @escaping (K.Value) -> Void) -> some View where K : PreferenceKey, K.Value : Equatable
}
사용 예시
1. 정의
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
2. GeometryReader를 사용하여 하위 뷰의 크기를 측정하고 preference로 전달.
struct ChildSizeView: View {
var body: some View {
Text("Child View")
.padding()
.background(Color.blue)
.overlay(
GeometryReader { geometry in
Color.clear
.preference(key: SizePreferenceKey.self, value: geometry.size) // 크기 전달
}
)
}
}
3. onPreferenceChange를 통해 크기를 수신하고 활용
struct ParentSizeView: View {
@State private var childSize: CGSize = .zero
var body: some View {
VStack {
Text("Child Size: \(childSize.width) x \(childSize.height)")
.font(.headline)
ChildSizeView() // 하위 뷰
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
.onPreferenceChange(SizePreferenceKey.self) { newSize in
childSize = newSize // 크기 업데이트
}
}
}
PreferenceKey를 사용하는 이유와 활용 사례
PreferenceKey는 다음과 같은 상황에서 유용합니다:
- 하위 뷰의 정보가 상위 뷰의 레이아웃이나 동작에 영향을 줄 때(스크롤 위치찾기)
- 하위 뷰의 크기나 위치 정보를 상위 뷰로 전달하여 동적으로 레이아웃을 구성.
- 상위 뷰가 다수의 하위 뷰 상태를 통합적으로 관리해야 할 때
- 여러 하위 뷰의 상태를 수집하여 하나의 상태로 병합.
- 커스텀 UI 컴포넌트 제작
- TabBar, Custom NavigationBar와 같은 UI 컴포넌트에서 동적으로 정보를 주고받기.
'SWIFTUI' 카테고리의 다른 글
ShareLink - 개발일기 (0) | 2024.11.09 |
---|---|
TCA- TestingCode (1) | 2024.10.26 |
TCA-Dependency...DI,DIP를 곁들인 (2) | 2024.09.20 |
TCA-3번째시간 Dependency (0) | 2024.07.19 |
TCA(2)-Store, ViewStore& Binding (4) | 2024.07.16 |