Argh! Byłeś tak blisko. Tak to się robi. Pominięto znak dolara (beta 3) lub podkreślenie (beta 4) i albo self przed właściwością amount, albo .value za parametrem amount. Wszystkie te opcje działają:
Zobaczysz, że usunąłem @State
in includeDecimal, sprawdź wyjaśnienie na końcu.
To jest użycie własności (wstaw 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
}
}
lub używając .value after (ale bez self, ponieważ używasz przekazanego parametru, a nie właściwości struktury):
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
}
}
To jest to samo, ale używamy różnych nazw dla parametru (withAmount) i właściwości (amount), więc wyraźnie widzisz, kiedy używasz każdego z nich.
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
}
}
Należy zauważyć, że wartość .value nie jest konieczna w przypadku właściwości, dzięki opakowaniu właściwości (@Binding), które tworzy metody dostępu, które sprawiają, że wartość .value jest niepotrzebna. Jednak z parametrem czegoś takiego nie ma i trzeba to zrobić wprost. Jeśli chcesz dowiedzieć się więcej o opakowaniach właściwości, zajrzyj do sesji WWDC 415 - Modern Swift API Design i przejdź do 23:12.
Jak odkryłeś, modyfikacja zmiennej @State w inicjatorze spowoduje zgłoszenie następującego błędu: Wątek 1: Błąd krytyczny: Dostęp do State poza View.body . Aby tego uniknąć, należy usunąć @State. Ma to sens, ponieważ includeDecimal nie jest źródłem prawdy. Jego wartość wynika z kwoty. Usunięcie @State includeDecimal
nie spowoduje jednak aktualizacji w przypadku zmiany kwoty. Aby to osiągnąć, najlepszą opcją jest zdefiniowanie parametru includeDecimal jako obliczonej właściwości, tak aby jego wartość pochodziła ze źródła prawdy (kwoty). W ten sposób za każdym razem, gdy zmienia się kwota, zmienia się również parametr includeDecimal. Jeśli Twój widok zależy od includeDecimal, powinien zostać zaktualizowany po zmianie:
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 { ... }
}
Jak wskazał rob mayoff , możesz również użyć $$varName
(beta 3) lub _varName
(beta4), aby zainicjować zmienną stanu:
$$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
odThread 1: Fatal error: Accessing State<Bool> outside View.body