Middle+
Mi az a PreferenceKey a SwiftUI kontextusában?
sobes.tech MI
Válasz az MI-től
A PreferenceKey egy protokoll a SwiftUI-ban, amely lehetővé teszi az értékek "lentől felfelé" történő továbbítását a nézetfa mentén. Ezt arra használják, hogy információkat gyűjtsenek az alárendelt nézetektől, és továbbítsák azokat a szülő nézetekhez, amelyek ezeket az információkat felhasználhatják viselkedésük vagy megjelenésük módosítására.
A PreferenceKey fő jellemzői:
- Protokoll: Implementálni kell a
PreferenceKeyprotokollt, meghatározva az érték típusát és az értékek összefoglalásának módját. associatedtype Value: Meghatározza az átadott adat típusát.static func reduce(value: inout Value, nextValue: () -> Value): Ezt a SwiftUI hívja meg, amikor több alárendelt nézettől gyűjti az értékeket. Meg kell határozni, hogyan egyesítse a jelenlegi (value) és az új (nextValue()) értékeket.- Értékek továbbítása: Az alárendelt nézetek a
.preference(key:value:)módosítót használják az érték beállítására egy adottPreferenceKey-hez. - Értékek olvasása: A szülő nézetek a
.onPreferenceChange(_:perform:)módosítót használják az érték változásainak figyelésére.
Példa:
Egy PreferenceKey létrehozása az alárendelt nézet magasságának meghatározására:
struct ChildHeightPreferenceKey: PreferenceKey {
// Értéktípus - opcionális Double, mivel az alárendelt nézet még nem rendelkezhet méretekkel
typealias Value = Double?
// Alapértelmezett érték
static var defaultValue: Double? = nil
// Értékek összefoglalása (ebben az esetben, az utolsó nem üres érték)
static func reduce(value: inout Double?, nextValue: () -> Double?) {
value = nextValue() ?? value
}
}
Használat a nézetben:
struct ParentView: View {
@State private var childHeight: Double? = nil
var body: some View {
VStack {
Text("Gyermek nézet magassága: \(childHeight != nil ? "\(childHeight!)" : "-")")
ChildView()
// A PreferenceKey értékének olvasása
.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) // Példa magasság
// PreferenceKey értékének beállítása
.preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
}
.frame(height: 100) // Fix keret a GeometryReader számára
}
}