Sobes.tech
Middle+

Mi az a PreferenceKey a SwiftUI kontextusában?

sobes.tech MI

Válasz az MI-től

A PreferenceKey egy protokoll a SwiftUI-ban, amely lehetővé teszi az értékek "lentől felfelé" történő továbbítását a nézetfa mentén. Ezt arra használják, hogy információkat gyűjtsenek az alárendelt nézetektől, és továbbítsák azokat a szülő nézetekhez, amelyek ezeket az információkat felhasználhatják viselkedésük vagy megjelenésük módosítására.

A PreferenceKey fő jellemzői:

  • Protokoll: Implementálni kell a PreferenceKey protokollt, meghatározva az érték típusát és az értékek összefoglalásának módját.
  • associatedtype Value: Meghatározza az átadott adat típusát.
  • static func reduce(value: inout Value, nextValue: () -> Value): Ezt a SwiftUI hívja meg, amikor több alárendelt nézettől gyűjti az értékeket. Meg kell határozni, hogyan egyesítse a jelenlegi (value) és az új (nextValue()) értékeket.
  • Értékek továbbítása: Az alárendelt nézetek a .preference(key:value:) módosítót használják az érték beállítására egy adott PreferenceKey-hez.
  • Értékek olvasása: A szülő nézetek a .onPreferenceChange(_:perform:) módosítót használják az érték változásainak figyelésére.

Példa:

Egy PreferenceKey létrehozása az alárendelt nézet magasságának meghatározására:

struct ChildHeightPreferenceKey: PreferenceKey {
    // Értéktípus - opcionális Double, mivel az alárendelt nézet még nem rendelkezhet méretekkel
    typealias Value = Double?

    // Alapértelmezett érték
    static var defaultValue: Double? = nil

    // Értékek összefoglalása (ebben az esetben, az utolsó nem üres érték)
    static func reduce(value: inout Double?, nextValue: () -> Double?) {
        value = nextValue() ?? value
    }
}

Használat a nézetben:

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

    var body: some View {
        VStack {
            Text("Gyermek nézet magassága: \(childHeight != nil ? "\(childHeight!)" : "-")")
            ChildView()
                // A PreferenceKey értékének olvasása
                .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) // Példa magasság
                // PreferenceKey értékének beállítása
                .preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
        }
        .frame(height: 100) // Fix keret a GeometryReader számára
    }
}