Sobes.tech
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 uma PreferenceKey específica.
  • Leitura de valores: As visualizações parentais usam o modificador .onPreferenceChange(_:perform:) para receber notificações quando o valor de uma PreferenceKey especí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
    }
}