Sobes.tech
Middle+

Wat is PreferenceKey in de context van SwiftUI?

sobes.tech AI

Antwoord van AI

PreferenceKey is een protocol in SwiftUI dat het mogelijk maakt om waarden "van onder naar boven" door de boom van views te sturen. Het wordt gebruikt om informatie van kind-views te verzamelen en aan ouder-views te leveren, die deze informatie kunnen gebruiken om hun gedrag of uiterlijk aan te passen.

Belangrijke kenmerken van PreferenceKey:

  • Protocol: Je moet het PreferenceKey protocol implementeren, waarbij je het type waarde en de methode voor het combineren van waarden definieert.
  • associatedtype Value: Bepaalt het datatype dat wordt doorgegeven.
  • static func reduce(value: inout Value, nextValue: () -> Value): Deze methode wordt door SwiftUI aangeroepen bij het verzamelen van waarden van meerdere kind-views. Je moet bepalen hoe je de huidige waarde (value) combineert met de nieuwe (nextValue()).
  • Waarden doorgeven: Kind-views gebruiken de modifier .preference(key:value:) om een waarde voor een specifieke PreferenceKey in te stellen.
  • Waarden lezen: Ouder-views gebruiken de modifier .onPreferenceChange(_:perform:) om notificaties te ontvangen over wijzigingen in de waarde van een PreferenceKey.

Voorbeeld:

Het maken van een PreferenceKey om de hoogte van een kind-view te bepalen:

struct ChildHeightPreferenceKey: PreferenceKey {
    // Type waarde - Optioneel Double, omdat de kind-view nog geen grootte kan hebben
    typealias Value = Double?

    // Standaardwaarde
    static var defaultValue: Double? = nil

    // Waarden samenvoegen (in dit geval, nemen we de laatste niet-nul waarde)
    static func reduce(value: inout Double?, nextValue: () -> Double?) {
        value = nextValue() ?? value
    }
}

Gebruik in de view:

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

    var body: some View {
        VStack {
            Text("Hoogte van de kind-view: \(childHeight != nil ? "\(childHeight!)" : "-")")
            ChildView()
                // Waarde van PreferenceKey lezen
                .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) // Voorbeeldhoogte
                // Waarde van PreferenceKey instellen
                .preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
        }
        .frame(height: 100) // Vaste frame voor GeometryReader
    }
}