Sobes.tech
Middle+

Kas yra PreferenceKey SwiftUI kontekste?

sobes.tech AI

Atsakymas iš AI

PreferenceKey — tai protokolas SwiftUI, leidžiantis perduoti reikšmes "iš apačios į viršų" per vaizdų medį. Jis naudojamas surinkti informaciją iš vaikų vaizdų ir perduoti ją tėvų vaizdams, kurie gali naudoti šią informaciją savo elgsenos ar išvaizdos keitimui.

PreferenceKey pagrindinės savybės:

  • Protokolas: Reikia įgyvendinti PreferenceKey protokolą, apibrėžiant reikšmės tipą ir metodą reikšmių sujungimui.
  • associatedtype Value: Nustato perduodamų duomenų tipą.
  • static func reduce(value: inout Value, nextValue: () -> Value): Šis metodas kviečiamas SwiftUI renkant reikšmes iš kelių vaikų vaizdų. Jūs turite nuspręsti, kaip sujungti esamą reikšmę (value) su nauja (nextValue()).
  • Reikšmių perdavimas: Vaikų vaizdai naudoja .preference(key:value:) modifikatorių, kad nustatytų reikšmę konkrečiam PreferenceKey.
  • Reikšmių skaitymas: Tėvų vaizdai naudoja .onPreferenceChange(_:perform:) modifikatorių, kad gautų pranešimus apie reikšmės pasikeitimus.

Pavyzdys:

Sukurkite PreferenceKey vaikų vaizdo aukščiui nustatyti:

struct ChildHeightPreferenceKey: PreferenceKey {
    // Reikšmės tipas - pasirenkamas Double, nes vaikų vaizdas dar gali neturėti matmenų
    typealias Value = Double?

    // Pradinė reikšmė
    static var defaultValue: Double? = nil

    // Reikšmių sujungimas (šiuo atveju, imame paskutinę ne tuščią reikšmę)
    static func reduce(value: inout Double?, nextValue: () -> Double?) {
        value = nextValue() ?? value
    }
}

Naudojimas vaizde:

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

    var body: some View {
        VStack {
            Text("Vaiko vaizdo aukštis: \(childHeight != nil ? "\(childHeight!)" : "-")")
            ChildView()
                // Reikšmės skaitymas
                .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) // Pavyzdinė aukštis
                // Reikšmės nustatymas
                .preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
        }
        .frame(height: 100) // Fiksuotas rėmas GeometryReader
    }
}