Ага! Ви були так близько. Ось як ви це робите. Ви пропустили знак долара (бета-версія 3) або підкреслення (бета-версія 4), або або перед вашим властивістю суми, або .value після параметра суми. Усі ці варіанти працюють:
Ви побачите, що я видалив @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) та властивості (суми), так що ви чітко бачите, коли ви використовуєте кожен з них.
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 - Сучасний дизайн API Swift і перейдіть до 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