Avatar
Avatar
udo223
SwiftUIで@Stateの変数にdidSetを書くとおかしな動作になる(didSet内が呼ばれない)。という記事をちらほら見かけたのですが私の環境では正しく動作しました。古い記事なので今は使えるみたいなことありますでしょうか?下記コードは私の環境では正しく動作しているように見えます。 やりたいこととしては、 enum AlertType { case responseError, internetConnectionError, unknownError } @State private var alertType: AlertType = .responseError { didSet { isShowAlert.toggle() } } @State private var isShowAlert = false のようにalertTypeに代入するだけでアラートを表示するようにしたいです。 (edited)
自分も理解できていなかったので今調べてみました。 @StateはdidSetだと全ての変更の際に呼ばれないため、@Stateの変更をトリガーにしたい場合は.onChangeを使うべきのようです。 alertType = .responseErrorではなく、alertType.wrappedValue = responseErrorのようにwrappedValueに直接変更を加えた時、wrappedValueはnonmutating setの値なのでdidSetは呼ばれません。Bindingした値を変更した時もwrappedValueが変更されるので同様です。 ここからは質問の回答とは逸れるのですが、 alertを表示していない時にもalertTypeに値が入っているのは違和感を感じたので、optionalにするかcaseにnoneを入れるのが良いかと思いました。 仮にoptionalにしたとして、今度は、alertが閉じられてshowAlertがfalseになった時にalertTypeをnilにしないといけないためshowAlertの変更を検知しないといけなさそうです。 それは冗長な気がするので、私はBinding時にこう書いてしまった方がわかりやすいと思いました。 Button { alertType = .responseError } label: { Text("アラート表示") } .alert( "alert", isPresented: .init( get: { alertType != nil }, set: { alertType = $0 ? alertType : nil } ), actions: {} ) 他の皆さんのご意見も聞いてみたいです。また、@Stateの解釈に誤りなどがありましたらご指摘いただけますと幸いです。
t_kansha 1