[解決済み] SwiftUIです。バインド変数でカスタムinitを実装する方法
質問
お金の入力画面を制作しているのですが、カスタムで
init
を使用して、初期化された金額に基づいて状態変数を設定します。
これでうまくいくと思ったのですが、コンパイラのエラーが出てしまいます。
Cannot assign value of type 'Binding<Double>' to type 'Double'
struct AmountView : View {
@Binding var amount: Double
@State var includeDecimal = false
init(amount: Binding<Double>) {
self.amount = amount
self.includeDecimal = round(amount)-amount > 0
}
...
}
解決方法は?
アーッ! あと少しだったのに こうやってやるんだ。ドル記号(ベータ3)かアンダースコア(ベータ4)、そして金額プロパティの前にself、または金額パラメータの後に.valueが抜けていますね。これらのオプションはすべて動作します。
を削除したのがわかると思います。
@State
で
includeDecimal
ということで、最後の説明をご覧ください。
これはプロパティ(selfを前に置く)を使っています。
struct AmountView : View {
@Binding var amount: Double
private var includeDecimal = false
init(amount: Binding<Double>) {
// self.$amount = amount // beta 3
self._amount = amount // beta 4
self.includeDecimal = round(self.amount)-self.amount > 0
}
}
または .value の後に使用します(ただし、構造体のプロパティではなく、渡されたパラメータを使用するため、self は使用しません)。
struct AmountView : View {
@Binding var amount: Double
private var includeDecimal = false
init(amount: Binding<Double>) {
// self.$amount = amount // beta 3
self._amount = amount // beta 4
self.includeDecimal = round(amount.value)-amount.value > 0
}
}
これも同じですが、パラメータ(withAmount)とプロパティ(amount)に異なる名前を使うことで、それぞれをいつ使っているのかが明確に分かるようにしています。
struct AmountView : View {
@Binding var amount: Double
private var includeDecimal = false
init(withAmount: Binding<Double>) {
// self.$amount = withAmount // beta 3
self._amount = withAmount // beta 4
self.includeDecimal = round(self.amount)-self.amount > 0
}
}
struct AmountView : View {
@Binding var amount: Double
private var includeDecimal = false
init(withAmount: Binding<Double>) {
// self.$amount = withAmount // beta 3
self._amount = withAmount // beta 4
self.includeDecimal = round(withAmount.value)-withAmount.value > 0
}
}
プロパティラッパー(@Binding)のおかげで、.valueは必要ありません。しかし、パラメータでは、そのようなものはなく、明示的に行う必要があります。プロパティ・ラッパーについてもっと知りたい場合は、以下のサイトを参照してください。 WWDCセッション415 - モダンなSwift APIデザイン をクリックし、23:12にジャンプしてください。
あなたが発見したように、initilizerから@State変数を変更すると、次のようなエラーが発生します。
スレッド 1: Fatal error: View.body の外側で State にアクセスしています
. これを避けるには、@Stateを削除するか、@Stateを削除する必要があります。これは、includeDecimalが真実の源ではないので、理にかなっています。その値は量から導かれます。しかし、@Stateを削除することで
includeDecimal
は、金額が変更されても更新されません。これを実現するための最良の方法は、includeDecimalをcomputedプロパティとして定義し、その値が真実の源(金額)から派生するようにすることです。この方法では、金額が変更されるたびに、includeDecimalも変更されます。もし、ビューがincludeDecimalに依存しているなら、それが変更されたときに更新される必要があります。
struct AmountView : View {
@Binding var amount: Double
private var includeDecimal: Bool {
return round(amount)-amount > 0
}
init(withAmount: Binding<Double>) {
self.$amount = withAmount
}
var body: some View { ... }
}
で示されるように
ロブ・メイヨフ
を使用することもできます。
$$varName
(ベータ3)、または
_varName
(β4)で状態変数を初期化します。
// Beta 3:
$$includeDecimal = State(initialValue: (round(amount.value) - amount.value) != 0)
// Beta 4:
_includeDecimal = State(initialValue: (round(amount.value) - amount.value) != 0)
関連
-
[解決済み] Swiftの@selector()?
-
[解決済み] Swiftでdispatch_onceのシングルトンモデルを使う
-
[解決済み] なぜクラスではなくストラクチャーを選ぶのか?
-
[解決済み] Swiftで乱数を生成する方法とは?
-
[解決済み】Swiftの辞書にキーが含まれているかどうかを判断し、その値を取得する。
-
[解決済み】「このアプリケーションはバックグラウンドのスレッドからオートレイアウトエンジンを変更しています」エラーが発生する?
-
[解決済み】dyld: ライブラリがロードされません。rpath/libswift_stdlib_core.dylib です。
-
[解決済み】swiftでDoubleを最も近いIntに丸めるには?
-
[解決済み】Swiftで列挙型の値の名前を取得する方法は?
-
[解決済み】Swiftで辞書に要素を追加する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Xcode 8 シェルスクリプト呼び出しエラー
-
[解決済み] iPhone Simulator.appと一緒にXcodeも外付けハードディスクにインストールできますか?
-
[解決済み] 型の不変値に変異型メンバを使用することはできません。
-
[解決済み] Swift Optionals - 条件の変数バインディングはイニシャライザを必要とする
-
[解決済み] SwiftUIのFacebookログイン。FacebookのIDをビューに戻すには?
-
[解決済み] Swiftで乱数を生成する方法とは?
-
[解決済み】Swiftで変数の型またはクラスを表示するにはどうすればよいですか?
-
[解決済み】Swiftで弱参照の配列を宣言するには?
-
[解決済み】Swiftで列挙型の値の名前を取得する方法は?
-
[解決済み】UIViewControllerの最上位機種を取得する。