Назад к вопросам
Middle+
345
questionbank
Что такое PreferenceKey в контексте SwiftUI?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech 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
}
}