Ах! Вы были так близки. Вот как вы это делаете. Вы пропустили знак доллара (бета 3) или подчеркивание (бета 4) и либо self перед свойством amount, либо .value после параметра amount. Все эти варианты работают:
Вы увидите, что я удалил @State
in includeDecimal, проверьте объяснение в конце.
Это использует свойство (поместите перед ним self):
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
}
}
Обратите внимание, что .value не требуется для свойства, благодаря оболочке свойства (@Binding), которая создает средства доступа, которые делают ненужным .value. Однако с параметром такого нет, и вы должны делать это явно. Если вы хотите узнать больше о оболочках свойств, посмотрите сеанс WWDC 415 - Современный дизайн Swift API и перейдите к 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 { ... }
}
Как указал Роб Майофф , вы также можете использовать $$varName
(beta 3) или _varName
(beta4) для инициализации переменной State:
$$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