Middle+
Čo je PreferenceKey v kontexte SwiftUI?
sobes.tech AI
Odpoveď od AI
PreferenceKey je protokol v SwiftUI, ktorý umožňuje prenášať hodnoty "zdola nahor" cez strom zobrazení. Používa sa na zber informácií od detských zobrazení a ich doručenie rodičovským, ktoré môžu tieto informácie použiť na zmenu svojho správania alebo vzhľadu.
Kľúčové vlastnosti PreferenceKey:
- Protokol: Je potrebné implementovať protokol
PreferenceKey, definovaním typu hodnoty a metódy na kombinovanie hodnôt. associatedtype Value: Určuje typ dát, ktorý bude prenášaný.static func reduce(value: inout Value, nextValue: () -> Value): Táto metóda sa volá od SwiftUI pri zbieraní hodnôt od viacerých detských zobrazení. Musíte určiť, ako spojiť aktuálnu hodnotu (value) s novou (nextValue()).- Prenos hodnôt: Detské zobrazenia používajú modifikátor
.preference(key:value:)na nastavenie hodnoty pre konkrétnyPreferenceKey. - Čítanie hodnôt: Rodičovské zobrazenia používajú modifikátor
.onPreferenceChange(_:perform:)na získanie oznámení o zmene hodnoty pre konkrétnyPreferenceKey.
Príklad:
Vytvorenie PreferenceKey na určenie výšky detského zobrazenia:
struct ChildHeightPreferenceKey: PreferenceKey {
// Typ hodnoty - voliteľný Double, pretože detské zobrazenie ešte nemusí mať rozmery
typealias Value = Double?
// Počiatočná hodnota
static var defaultValue: Double? = nil
// Zlučovanie hodnôt (v tomto prípade, berieme poslednú nevyplnenú hodnotu)
static func reduce(value: inout Double?, nextValue: () -> Double?) {
value = nextValue() ?? value
}
}
Použitie v zobrazení:
struct ParentView: View {
@State private var childHeight: Double? = nil
var body: some View {
VStack {
Text("Výška detského zobrazenia: \(childHeight != nil ? "\(childHeight!)" : "-")")
ChildView()
// Čítanie 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) // Príklad výšky
// Nastavenie hodnoty PreferenceKey
.preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
}
.frame(height: 100) // Fixná rámček pre GeometryReader
}
}