Sobes.tech
Middle+

Τι είναι το PreferenceKey στο πλαίσιο του SwiftUI;

sobes.tech AI

Απάντηση από AI

Το PreferenceKey είναι ένα πρωτόκολλο στο SwiftUI που επιτρέπει τη μετάδοση τιμών "από κάτω προς τα πάνω" μέσα από το δέντρο των προβολών. Χρησιμοποιείται για τη συλλογή πληροφοριών από τις παιδικές προβολές και την παράδοσή τους στις γονικές προβολές, που μπορούν να χρησιμοποιήσουν αυτές τις πληροφορίες για να αλλάξουν τη συμπεριφορά ή την εμφάνισή τους.

Κύρια χαρακτηριστικά του PreferenceKey:

  • Πρωτόκολλο: Πρέπει να υλοποιήσετε το πρωτόκολλο PreferenceKey, ορίζοντας τον τύπο της τιμής και τη μέθοδο για το συνδυασμό των τιμών.
  • associatedtype Value: Ορίζει τον τύπο δεδομένων που θα μεταδοθεί.
  • static func reduce(value: inout Value, nextValue: () -> Value): Αυτή η μέθοδος καλείται από το SwiftUI κατά τη συλλογή τιμών από πολλές παιδικές προβολές. Πρέπει να ορίσετε πώς να συνδυάσετε την τρέχουσα τιμή (value) με τη νέα (nextValue()).
  • Μετάδοση τιμών: Οι παιδικές προβολές χρησιμοποιούν τον τροποποιητή .preference(key:value:) για να ορίσουν μια τιμή για ένα συγκεκριμένο PreferenceKey.
  • Ανάγνωση τιμών: Οι γονικές προβολές χρησιμοποιούν τον τροποποιητή .onPreferenceChange(_:perform:) για να λαμβάνουν ειδοποιήσεις όταν αλλάξει η τιμή για ένα συγκεκριμένο PreferenceKey.

Παράδειγμα:

Δημιουργία PreferenceKey για τον καθορισμό του ύψους μιας παιδικής προβολής:

struct ChildHeightPreferenceKey: PreferenceKey {
    // Τύπος τιμής - Προαιρετικό Double, καθώς η παιδική προβολή μπορεί ακόμα να μην έχει διαστάσεις
    typealias Value = Double?

    // Προεπιλεγμένη τιμή
    static var defaultValue: Double? = nil

    // Συνένωση τιμών (σε αυτήν την περίπτωση, παίρνουμε την τελευταία μη κενή τιμή)
    static func reduce(value: inout Double?, nextValue: () -> Double?) {
        value = nextValue() ?? value
    }
}

Χρήση στην προβολή:

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

    var body: some View {
        VStack {
            Text("Ύψος παιδικής προβολής: \(childHeight != nil ? "\(childHeight!)" : "-")")
            ChildView()
                // Ανάγνωση της τιμής του 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) // Παράδειγμα ύψους
                // Ορισμός της τιμής του PreferenceKey
                .preference(key: ChildHeightPreferenceKey.self, value: geometry.size.height)
        }
        .frame(height: 100) // Σταθερό πλαίσιο για το GeometryReader
    }
}