Middle+
Cos'è PreferenceKey nel contesto di SwiftUI?
sobes.tech AI
Risposta dell'AI
PreferenceKey è un protocollo in SwiftUI che consente di trasmettere valori "dal basso verso l'alto" attraverso l'albero delle visualizzazioni. Viene utilizzato per raccogliere informazioni dalle visualizzazioni figlie e consegnarle alle visualizzazioni genitore, che possono usare queste informazioni per modificare il proprio comportamento o aspetto.
Caratteristiche principali di PreferenceKey:
- Protocolo: È necessario implementare il protocollo
PreferenceKey, definendo il tipo di valore e il metodo per combinarli. associatedtype Value: Definisce il tipo di dati che verrà trasmesso.static func reduce(value: inout Value, nextValue: () -> Value): Questo metodo viene chiamato da SwiftUI durante la raccolta dei valori da più visualizzazioni figlie. Devi definire come combinare il valore corrente (value) con il nuovo (nextValue()).- Trasmissione dei valori: Le visualizzazioni figlie usano il modificatore
.preference(key:value:)per impostare un valore per unaPreferenceKeyspecifica. - Lettura dei valori: Le visualizzazioni genitore usano il modificatore
.onPreferenceChange(_:perform:)per ricevere notifiche quando il valore di unaPreferenceKeycambia.
Esempio:
Creazione di una PreferenceKey per determinare l'altezza di una visualizzazione figlia:
struct ChildHeightPreferenceKey: PreferenceKey {
// Tipo di valore - Double opzionale, poiché la visualizzazione figlia potrebbe non avere ancora dimensioni
typealias Value = Double?
// Valore di default
static var defaultValue: Double? = nil
// Unione dei valori (in questo caso, prendi l'ultimo valore non nullo)
static func reduce(value: inout Double?, nextValue: () -> Double?) {
value = nextValue() ?? value
}
}
Utilizzo nella visualizzazione:
struct ParentView: View {
@State private var childHeight: Double? = nil
var body: some View {
VStack {
Text("Altezza della visualizzazione figlia: \(childHeight != nil ? "\(childHeight!)" : "-")")
ChildView()
// Lettura del valore di 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) // Esempio di altezza
// Impostazione del valore di PreferenceKey
.preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
}
.frame(height: 100) // Cornice fissa per GeometryReader
}
}