ああ!あなたはとても近かった。これがあなたのやり方です。ドル記号(ベータ3)またはアンダースコア(ベータ4)を見逃し、金額プロパティの前に自分自身があるか、金額パラメーターの後に.valueがあります。これらのオプションはすべて機能します。
@State
includeDecimalを削除したことがわかります。最後に、説明を確認してください。
これはプロパティを使用しています(その前に自分自身を置きます):
struct AmountView : View {
@Binding var amount: Double
private var includeDecimal = false
init(amount: Binding<Double>) {
self._amount = amount
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
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
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
self.includeDecimal = round(withAmount.value)-withAmount.value > 0
}
}
プロパティラッパー(@Binding)のおかげで、.valueはプロパティに必要ないことに注意してください。これにより、.valueが不要になるアクセサーが作成されます。ただし、パラメータではそのようなことはなく、明示的に行う必要があります。プロパティラッパーについて詳しく知りたい場合は、 WWDCセッション415-Modern Swift API Designを 23:12にジャンプしてください。
ご存知のとおり、イニシライザーから@State変数を変更すると、次のエラーがスローされます。スレッド1:致命的なエラー:View.bodyの外部の状態にアクセスしています。これを回避するには、@ Stateを削除する必要があります。includeDecimalは信頼できる情報源ではないため、これは理にかなっています。その値は金額から導き出されます。ただし、@ Stateを削除すると、includeDecimal
金額が変更されても更新されません。これを実現するための最良のオプションは、includeDecimalを計算されたプロパティとして定義し、その値が信頼できる情報源(金額)から導出されるようにすることです。このように、金額が変更されるたびに、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 { ... }
}
rob mayoffで示されているように、$$varName
(beta 3)または_varName
(beta4)を使用して状態変数を初期化することもできます。
$$includeDecimal = State(initialValue: (round(amount.value) - amount.value) != 0)
_includeDecimal = State(initialValue: (round(amount.value) - amount.value) != 0)
self.includeDecimal = round(self.amount)-self.amount > 0
がThread 1: Fatal error: Accessing State<Bool> outside View.body