Sobes.tech
Middle+

Was ist PreferenceKey im Kontext von SwiftUI?

sobes.tech KI

Antwort von AI

PreferenceKey ist ein Protokoll in SwiftUI, das das Übertragen von Werten "von unten nach oben" durch den View-Baum ermöglicht. Es wird verwendet, um Informationen von Kind-Views zu sammeln und an Eltern-Views zu liefern, die diese Informationen nutzen können, um ihr Verhalten oder Aussehen zu ändern.

Wichtige Merkmale von PreferenceKey:

  • Protokoll: Es ist notwendig, das PreferenceKey-Protokoll zu implementieren, wobei der Werttyp und die Methode zum Kombinieren der Werte definiert werden.
  • associatedtype Value: Bestimmt den Datentyp, der übertragen wird.
  • static func reduce(value: inout Value, nextValue: () -> Value): Diese Methode wird von SwiftUI beim Sammeln von Werten aus mehreren Kind-Views aufgerufen. Hier muss definiert werden, wie der aktuelle Wert (value) mit dem neuen (nextValue()) kombiniert wird.
  • Wertübertragung: Kind-Views verwenden den Modifikator .preference(key:value:), um einen Wert für eine bestimmte PreferenceKey zu setzen.
  • Wertlesen: Eltern-Views verwenden den Modifikator .onPreferenceChange(_:perform:), um Benachrichtigungen über Änderungen des Wertes einer bestimmten PreferenceKey zu erhalten.

Beispiel:

Erstellen einer PreferenceKey, um die Höhe einer Kind-View zu bestimmen:

struct ChildHeightPreferenceKey: PreferenceKey {
    // Werttyp - Optional Double, da die Kind-View möglicherweise noch keine Größe hat
    typealias Value = Double?

    // Standardwert
    static var defaultValue: Double? = nil

    // Werte zusammenführen (in diesem Fall, den letzten nicht-leeren Wert nehmen)
    static func reduce(value: inout Double?, nextValue: () -> Double?) {
        value = nextValue() ?? value
    }
}

Verwendung in der View:

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

    var body: some View {
        VStack {
            Text("Höhe der Kind-View: \(childHeight != nil ? "\(childHeight!)" : "-")")
            ChildView()
                // Lesen des PreferenceKey-Wertes
                .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) // Beispielhöhe
                // Setzen des PreferenceKey-Wertes
                .preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
        }
        .frame(height: 100) // Fester Rahmen für GeometryReader
    }
}