Middle+
O que é PreferenceKey no contexto do SwiftUI?
sobes.tech IA
Resposta da IA
PreferenceKey é um protocolo no SwiftUI que permite transmitir valores "de baixo para cima" através da árvore de visualizações. É usado para recolher informações de visualizações filhas e entregá-las às visualizações parentais, que podem usar essas informações para alterar seu comportamento ou aparência.
Características principais do PreferenceKey:
- Protocolo: É necessário implementar o protocolo
PreferenceKey, definindo o tipo de valor e o método para combinar valores. associatedtype Value: Define o tipo de dados que será transmitido.static func reduce(value: inout Value, nextValue: () -> Value): Este método é chamado pelo SwiftUI ao recolher valores de várias visualizações filhas. Você deve definir como combinar o valor atual (value) com o novo (nextValue()).- Transmissão de valores: As visualizações filhas usam o modificador
.preference(key:value:)para definir um valor para umaPreferenceKeyespecífica. - Leitura de valores: As visualizações parentais usam o modificador
.onPreferenceChange(_:perform:)para receber notificações quando o valor de umaPreferenceKeyespecífica mudar.
Exemplo:
Criando uma PreferenceKey para determinar a altura de uma visualização filha:
struct ChildHeightPreferenceKey: PreferenceKey {
// Tipo de valor - Double opcional, pois a visualização filha pode ainda não ter tamanhos
typealias Value = Double?
// Valor padrão
static var defaultValue: Double? = nil
// Combinar valores (neste caso, pegar o último valor não nulo)
static func reduce(value: inout Double?, nextValue: () -> Double?) {
value = nextValue() ?? value
}
}
Uso na visualização:
struct ParentView: View {
@State private var childHeight: Double? = nil
var body: some View {
VStack {
Text("Altura da visualização filha: \(childHeight != nil ? "\(childHeight!)" : "-")")
ChildView()
// Ler o 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) // Exemplo de altura
// Definir o valor de PreferenceKey
.preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
}
.frame(height: 100) // Quadro fixo para GeometryReader
}
}