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 bestimmtePreferenceKeyzu setzen. - Wertlesen: Eltern-Views verwenden den Modifikator
.onPreferenceChange(_:perform:), um Benachrichtigungen über Änderungen des Wertes einer bestimmtenPreferenceKeyzu 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
}
}