Dans ma vue SwiftUI, je dois déclencher une action lorsqu'un Toggle () change son état. La bascule elle-même ne prend qu'une liaison. J'ai donc essayé de déclencher l'action dans le didSet de la variable @State. Mais le didSet n'est jamais appelé.
Existe-t-il un (autre) moyen de déclencher une action? Ou un moyen d'observer le changement de valeur d'une variable @State?
Mon code ressemble à ceci:
struct PWSDetailView : View {
@ObjectBinding var station: PWS
@State var isDisplayed: Bool = false {
didSet {
if isDisplayed != station.isDisplayed {
PWSStore.shared.toggleIsDisplayed(station)
}
}
}
var body: some View {
VStack {
ZStack(alignment: .leading) {
Rectangle()
.frame(width: UIScreen.main.bounds.width, height: 50)
.foregroundColor(Color.lokalZeroBlue)
Text(station.displayName)
.font(.title)
.foregroundColor(Color.white)
.padding(.leading)
}
MapView(latitude: station.latitude, longitude: station.longitude, span: 0.05)
.frame(height: UIScreen.main.bounds.height / 3)
.padding(.top, -8)
Form {
Toggle(isOn: $isDisplayed)
{ Text("Wetterstation anzeigen") }
}
Spacer()
}.colorScheme(.dark)
}
}
Le comportement souhaité serait que l'action "PWSStore.shared.toggleIsDisplayed (station)" est déclenchée lorsque Toggle () change son état.
Tout d'abord, savez-vous réellement que les notifications KVO supplémentaires pour station.isDisplayed
sont un problème? Vous rencontrez des problèmes de performances? Sinon, ne vous en faites pas.
Si vous rencontrez des problèmes de performances et que vous avez établi qu'ils sont dus à un excès de station.isDisplayed
Notifications KVO, alors la prochaine chose à essayer est d'éliminer les notifications KVO inutiles. Pour ce faire, vous passez aux notifications KVO manuelles.
Ajoutez cette méthode à la définition de classe de station
:
@objc class var automaticallyNotifiesObserversOfIsDisplayed: Bool { return false }
Et utilisez les observateurs willSet
et didSet
de Swift pour notifier manuellement les observateurs KVO, mais uniquement si la valeur change:
@objc dynamic var isDisplayed = false {
willSet {
if isDisplayed != newValue { willChangeValue(for: \.isDisplayed) }
}
didSet {
if isDisplayed != oldValue { didChangeValue(for: \.isDisplayed) }
}
}
class PWSStore : ObservableObject {
...
var station: PWS
@Published var isDisplayed = true {
willSet {
PWSStore.shared.toggleIsDisplayed(self.station)
}
}
}
struct PWSDetailView : View {
@ObservedObject var station = PWSStore.shared
...
var body: some View {
...
Toggle(isOn: $isDisplayed) { Text("Wetterstation anzeigen") }
...
}
}
Démo ici https://youtu.be/N8pL7uTjEFM