SwiftUIビューでは、Toggle()が状態を変更したときにアクションをトリガーする必要があります。トグル自体はバインディングのみを受け取ります。したがって、@ State変数のdidSetでアクションをトリガーしようとしました。しかし、didSetが呼び出されることはありません。
アクションをトリガーする(他の)方法はありますか?または、@ State変数の値の変化を観察する方法はありますか?
私のコードは次のようになります:
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)
}
}
望ましい動作は、Toggle()が状態を変更したときにアクション「PWSStore.shared.toggleIsDisplayed(station)」がトリガーされることです。
まず、station.isDisplayed
の追加のKVO通知が問題であることを実際に知っていますか?パフォーマンスの問題が発生していますか?そうでない場合は、心配する必要はありません。
パフォーマンスの問題が発生していて、それらが過度のstation.isDisplayed
KVO通知によるものであることが判明した場合、次に試すことは、不要なKVO通知を排除することです。これは、手動のKVO通知に切り替えることによって行います。
このメソッドをstation
のクラス定義に追加します。
@objc class var automaticallyNotifiesObserversOfIsDisplayed: Bool { return false }
また、SwiftのwillSet
およびdidSet
オブザーバーを使用して、手動でKVOオブザーバーに通知しますが、値が変化している場合のみです。
@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") }
...
}
}
デモはこちら https://youtu.be/N8pL7uTjEFM