Sobes.tech
Middle+

Čo je PreferenceKey v kontexte SwiftUI?

sobes.tech AI

Odpoveď od AI

PreferenceKey je protokol v SwiftUI, ktorý umožňuje prenášať hodnoty "zdola nahor" cez strom zobrazení. Používa sa na zber informácií od detských zobrazení a ich doručenie rodičovským, ktoré môžu tieto informácie použiť na zmenu svojho správania alebo vzhľadu.

Kľúčové vlastnosti PreferenceKey:

  • Protokol: Je potrebné implementovať protokol PreferenceKey, definovaním typu hodnoty a metódy na kombinovanie hodnôt.
  • associatedtype Value: Určuje typ dát, ktorý bude prenášaný.
  • static func reduce(value: inout Value, nextValue: () -> Value): Táto metóda sa volá od SwiftUI pri zbieraní hodnôt od viacerých detských zobrazení. Musíte určiť, ako spojiť aktuálnu hodnotu (value) s novou (nextValue()).
  • Prenos hodnôt: Detské zobrazenia používajú modifikátor .preference(key:value:) na nastavenie hodnoty pre konkrétny PreferenceKey.
  • Čítanie hodnôt: Rodičovské zobrazenia používajú modifikátor .onPreferenceChange(_:perform:) na získanie oznámení o zmene hodnoty pre konkrétny PreferenceKey.

Príklad:

Vytvorenie PreferenceKey na určenie výšky detského zobrazenia:

struct ChildHeightPreferenceKey: PreferenceKey {
    // Typ hodnoty - voliteľný Double, pretože detské zobrazenie ešte nemusí mať rozmery
    typealias Value = Double?

    // Počiatočná hodnota
    static var defaultValue: Double? = nil

    // Zlučovanie hodnôt (v tomto prípade, berieme poslednú nevyplnenú hodnotu)
    static func reduce(value: inout Double?, nextValue: () -> Double?) {
        value = nextValue() ?? value
    }
}

Použitie v zobrazení:

struct ParentView: View {
    @State private var childHeight: Double? = nil

    var body: some View {
        VStack {
            Text("Výška detského zobrazenia: \(childHeight != nil ? "\(childHeight!)" : "-")")
            ChildView()
                // Čítanie hodnoty PreferenceKey
                .onPreferenceChange(ChildHeightPreferenceKey.self) { newValue in
                    self.childHeight = newValue
                }
        }
    }
}

struct ChildView: View {
    var body: some View {
        GeometryReader { geometry in
            Rectangle()
                .fill(Color.blue)
                .frame(height: 100) // Príklad výšky
                // Nastavenie hodnoty PreferenceKey
                .preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
        }
        .frame(height: 100) // Fixná rámček pre GeometryReader
    }
}