Middle+
Какво е PreferenceKey в контекста на SwiftUI?
sobes.tech AI
Отговор от AI
PreferenceKey — това е протокол в SwiftUI, който позволява да се предават стойности "отдолу нагоре" по дървото на представленията. Той се използва за събиране на информация от дъщерните представления и доставянето й на родителските, които могат да използват тази информация за промяна на поведението или външния вид.
Ключови характеристики на PreferenceKey:
- Протокол: Трябва да реализирате протокола
PreferenceKey, като определите типа на стойността и метода за комбиниране на стойностите. associatedtype Value: Определя типа данни, който ще бъде предаван.static func reduce(value: inout Value, nextValue: () -> Value): Този метод се извиква от SwiftUI при събиране на стойности от няколко дъщерни представления. Трябва да определите как да обедините текущата стойност (value) с новата (nextValue()).- Предаване на стойности: Дъщерните представления използват модификатора
.preference(key:value:)за задаване на стойност за конкретенPreferenceKey. - Четене на стойности: Родителските представления използват модификатора
.onPreferenceChange(_:perform:)за получаване на уведомления за промяна на стойността за конкретенPreferenceKey.
Пример:
Създаване на PreferenceKey за определяне на височината на дъщерното представяне:
struct ChildHeightPreferenceKey: PreferenceKey {
// Типът на стойността - Optional Double, тъй като дъщерното представяне все още може да няма размери
typealias Value = Double?
// Начална стойност
static var defaultValue: Double? = nil
// Обединяване на стойности (в този случай, вземаме последната непразна стойност)
static func reduce(value: inout Double?, nextValue: () -> Double?) {
value = nextValue() ?? value
}
}
Използване в представление:
struct ParentView: View {
@State private var childHeight: Double? = nil
var body: some View {
VStack {
Text("Височината на дъщерното представяне: \(childHeight != nil ? "\(childHeight!)" : "-")")
ChildView()
// Четене на стойността на 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) // Примерна височина
// Задаване на стойност на PreferenceKey
.preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
}
.frame(height: 100) // Фиксирана рамка за GeometryReader
}
}