Preference Key

2024. 11. 25. 18:23·SWIFT개발

PreferenceKey는 하위 뷰에서 상위 뷰로 데이터를 전달하기 위한 메커니즘입니다. 일반적으로 SwiftUI는 데이터가 상위 뷰에서 하위 뷰로 전달되는 구조를 따르지만, PreferenceKey는 그 반대 흐름을 가능하게 해줍니다.

PreferenceKey의 주요 구성 요소

PreferenceKey는 다음과 같이 세 가지 주요 요소로 이루어집니다:

  1. 키 등록: PreferenceKey 프로토콜 준수 및 타입 정의
  2. 값 송신: 하위 뷰에서 preference 메소드를 통해 값 전달
  3. 값 수신: 상위 뷰에서 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는 다음과 같은 상황에서 유용합니다:

  1. 하위 뷰의 정보가 상위 뷰의 레이아웃이나 동작에 영향을 줄 때(스크롤 위치찾기)
    • 하위 뷰의 크기나 위치 정보를 상위 뷰로 전달하여 동적으로 레이아웃을 구성.
  2. 상위 뷰가 다수의 하위 뷰 상태를 통합적으로 관리해야 할 때
    • 여러 하위 뷰의 상태를 수집하여 하나의 상태로 병합.
  3. 커스텀 UI 컴포넌트 제작
    • TabBar, Custom NavigationBar와 같은 UI 컴포넌트에서 동적으로 정보를 주고받기.

 

'SWIFT개발' 카테고리의 다른 글

Memory Leak을 찾아보자 실전편(1)  (0) 2025.01.14
Alamofire error code handling  (5) 2024.12.17
ShareLink - 개발일기  (1) 2024.11.09
TCA- TestingCode  (1) 2024.10.26
CLMonitor  (1) 2024.10.22
'SWIFT개발' 카테고리의 다른 글
  • Memory Leak을 찾아보자 실전편(1)
  • Alamofire error code handling
  • ShareLink - 개발일기
  • TCA- TestingCode
2료일
2료일
좌충우돌 모든것을 다 정리하려고 노력하는 J가 되려고 하는 세미개발자의 블로그입니다. 편하게 보고 가세요
  • 2료일
    GPT에게서 살아남기
    2료일
  • 전체
    오늘
    어제
    • 분류 전체보기 (121) N
      • SWIFT개발 (29)
      • 알고리즘 (25)
      • Design (6)
      • ARkit (1)
      • 면접준비 (30)
      • UIkit (2)
      • Vapor-Server with swift (3)
      • 디자인패턴 (5)
      • 반응형프로그래밍 (12)
      • CS (3)
      • 도서관 (2) N
  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
2료일
Preference Key
상단으로

티스토리툴바