Middle+
Co je PreferenceKey v kontextu SwiftUI?
sobes.tech AI
Odpověď od AI
PreferenceKey je protokol ve SwiftUI, který umožňuje přenos hodnot "zdola nahoru" přes strom pohledů. Používá se ke sběru informací od podřízených pohledů a jejich doručení rodičovským, které tyto informace mohou využít ke změně svého chování nebo vzhledu.
Klíčové vlastnosti PreferenceKey:
- Protokol: Je nutné implementovat protokol
PreferenceKey, který definuje typ hodnoty a metodu pro jejich slučování. associatedtype Value: Určuje typ dat, která budou přenášena.static func reduce(value: inout Value, nextValue: () -> Value): Tato metoda je volána SwiftUI při sběru hodnot od více podřízených pohledů. Musíte definovat, jak sloučit aktuální hodnotu (value) s novou (nextValue()).- Přenášení hodnot: Podřízené pohledy používají modifikátor
.preference(key:value:)k nastavení hodnoty pro konkrétníPreferenceKey. - Čtení hodnot: Rodičovské pohledy používají modifikátor
.onPreferenceChange(_:perform:)k získání oznámení o změně hodnoty pro konkrétníPreferenceKey.
Příklad:
Vytvoření PreferenceKey pro určení výšky podřízeného pohledu:
struct ChildHeightPreferenceKey: PreferenceKey {
// Typ hodnoty - volitelný Double, protože podřízený pohled ještě nemusí mít rozměry
typealias Value = Double?
// Výchozí hodnota
static var defaultValue: Double? = nil
// Sloučení hodnot (v tomto případě, vezmeme poslední nenulovou hodnotu)
static func reduce(value: inout Double?, nextValue: () -> Double?) {
value = nextValue() ?? value
}
}
Použití v pohledu:
struct ParentView: View {
@State private var childHeight: Double? = nil
var body: some View {
VStack {
Text("Výška podřízeného pohledu: \(childHeight != nil ? "\(childHeight!)" : "-")")
ChildView()
// Čtení 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) // Příklad výšky
// Nastavení hodnoty PreferenceKey
.preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
}
.frame(height: 100) // Pevný rám pro GeometryReader
}
}