Middle+
¿Qué es PreferenceKey en el contexto de SwiftUI?
sobes.tech AI
Respuesta de la IA
PreferenceKey es un protocolo en SwiftUI que permite transmitir valores "de abajo hacia arriba" a través del árbol de vistas. Se utiliza para recopilar información de vistas hijas y entregarla a las vistas padres, que pueden usar esta información para modificar su comportamiento o apariencia.
Características clave de PreferenceKey:
- Protocolo: Es necesario implementar el protocolo
PreferenceKey, definiendo el tipo de valor y el método para combinar valores. associatedtype Value: Define el tipo de datos que se transmitirá.static func reduce(value: inout Value, nextValue: () -> Value): Este método es llamado por SwiftUI al recopilar valores de varias vistas hijas. Debes definir cómo combinar el valor actual (value) con el nuevo (nextValue()).- Transmisión de valores: Las vistas hijas usan el modificador
.preference(key:value:)para establecer un valor para unaPreferenceKeyespecífica. - Lectura de valores: Las vistas padres usan el modificador
.onPreferenceChange(_:perform:)para recibir notificaciones cuando cambie el valor de unaPreferenceKeyespecífica.
Ejemplo:
Creando una PreferenceKey para determinar la altura de una vista hija:
struct ChildHeightPreferenceKey: PreferenceKey {
// Tipo de valor - Double opcional, ya que la vista hija puede no tener tamaño aún
typealias Value = Double?
// Valor predeterminado
static var defaultValue: Double? = nil
// Combinar valores (en este caso, tomamos el último valor no nulo)
static func reduce(value: inout Double?, nextValue: () -> Double?) {
value = nextValue() ?? value
}
}
Uso en la vista:
struct ParentView: View {
@State private var childHeight: Double? = nil
var body: some View {
VStack {
Text("Altura de la vista hija: \(childHeight != nil ? "\(childHeight!)" : "-")")
ChildView()
// Leer el valor de 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) // Ejemplo de altura
// Establecer el valor de PreferenceKey
.preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
}
.frame(height: 100) // Marco fijo para GeometryReader
}
}