Argh! Du warst so nah. Das ist wie man es macht. Sie haben ein Dollarzeichen (Beta 3) oder einen Unterstrich (Beta 4) verpasst und entweder sich selbst vor Ihrer Betragseigenschaft oder einen Wert nach dem Betragsparameter. Alle diese Optionen funktionieren:
Sie werden sehen, dass ich das @State
in includeDecimal entfernt habe. Überprüfen Sie die Erklärung am Ende.
Dies nutzt die Eigenschaft (stellen Sie sich davor):
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
}
}
oder mit .value after (aber ohne self, da Sie den übergebenen Parameter verwenden, nicht die Eigenschaft der Struktur):
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
}
}
Dies ist das gleiche, aber wir verwenden unterschiedliche Namen für den Parameter (withAmount) und die Eigenschaft (Betrag), sodass Sie deutlich sehen, wann Sie jeden verwenden.
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
}
}
Beachten Sie, dass der Wert für die Eigenschaft dank des Eigenschafts-Wrappers (@Binding) nicht erforderlich ist, der die Accessoren erstellt, die den Wert unnötig machen. Mit dem Parameter gibt es so etwas jedoch nicht und Sie müssen es explizit tun. Wenn Sie mehr über Property Wrapper erfahren möchten, lesen Sie die WWDC-Sitzung 415 - Modern Swift API Design und springen Sie zu 23:12.
Wie Sie festgestellt haben, wird beim Ändern der Variablen @State im Initilizer der folgende Fehler ausgegeben: Thread 1: Schwerwiegender Fehler: Zugriff auf den Status außerhalb von View.body . Um dies zu vermeiden, sollten Sie entweder den @State entfernen. Was Sinn macht, weil includeDecimal keine Quelle der Wahrheit ist. Sein Wert wird aus der Menge abgeleitet. Durch Entfernen von @State wird jedoch includeDecimal
nicht aktualisiert, wenn sich der Betrag ändert. Um dies zu erreichen, ist es am besten, Ihr includeDecimal als berechnete Eigenschaft zu definieren, damit sein Wert von der Quelle der Wahrheit (Menge) abgeleitet wird. Auf diese Weise funktioniert auch includeDecimal, wenn sich der Betrag ändert. Wenn Ihre Ansicht von includeDecimal abhängt, sollte sie aktualisiert werden, wenn sie sich ändert:
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 { ... }
}
Wie von rob mayoff angegeben , können Sie auch $$varName
(Beta 3) oder _varName
(Beta4) verwenden, um eine Statusvariable zu initialisieren:
$$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
derThread 1: Fatal error: Accessing State<Bool> outside View.body