Sobes.tech
Middle+

Ce este PreferenceKey în contextul SwiftUI?

sobes.tech AI

Răspuns de la AI

PreferenceKey este un protocol în SwiftUI care permite transmiterea valorilor "de jos în sus" prin arborele de vizualizări. Este utilizat pentru colectarea informațiilor de la vizualizările copil și livrarea acestora către vizualizările părinte, care pot folosi aceste informații pentru a-și modifica comportamentul sau aspectul.

Caracteristici cheie ale PreferenceKey:

  • Protocol: Este necesar să implementați protocolul PreferenceKey, definind tipul de valoare și metoda de combinare a valorilor.
  • associatedtype Value: Definește tipul de date care va fi transmis.
  • static func reduce(value: inout Value, nextValue: () -> Value): Această metodă este apelată de SwiftUI în timpul colectării valorilor de la mai multe vizualizări copil. Trebuie să definiți cum să combinați valoarea curentă (value) cu cea nouă (nextValue()).
  • Transmiterea valorilor: Vizualizările copil utilizează modificatorul .preference(key:value:) pentru a seta o valoare pentru o PreferenceKey specifică.
  • Citirea valorilor: Vizualizările părinte utilizează modificatorul .onPreferenceChange(_:perform:) pentru a primi notificări despre modificarea valorii pentru o PreferenceKey specifică.

Exemplu:

Crearea unei PreferenceKey pentru a determina înălțimea unei vizualizări copil:

struct ChildHeightPreferenceKey: PreferenceKey {
    // Tipul valorii - Double opțional, deoarece vizualizarea copil poate să nu aibă încă dimensiuni
    typealias Value = Double?

    // Valoarea implicită
    static var defaultValue: Double? = nil

    // Combinarea valorilor (în acest caz, luăm ultima valoare nenulă)
    static func reduce(value: inout Double?, nextValue: () -> Double?) {
        value = nextValue() ?? value
    }
}

Utilizare în vizualizare:

struct ParentView: View {
    @State private var childHeight: Double? = nil

    var body: some View {
        VStack {
            Text("Înălțimea vizualizării copil: \(childHeight != nil ? "\(childHeight!)" : "-")")
            ChildView()
                // Citirea valorii 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) // Exemplu de înălțime
                // Setarea valorii PreferenceKey
                .preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
        }
        .frame(height: 100) // Cadru fix pentru GeometryReader
    }
}