Argh! Você estava tão perto. É assim que se faz. Você perdeu um cifrão (beta 3) ou sublinhado (beta 4), e mesmo na frente de sua propriedade de valor, ou .value após o parâmetro de valor. Todas essas opções funcionam:
Você verá que removi o @State
in includeDecimal, verifique a explicação no final.
Isso é usar a propriedade (coloque-se na frente dela):
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
}
}
ou usando .value after (mas sem self, porque você está usando o parâmetro passado, não a propriedade da estrutura):
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
}
}
É o mesmo, mas usamos nomes diferentes para o parâmetro (withAmount) e a propriedade (amount), para que você veja claramente quando está usando cada um.
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
}
}
Observe que .value não é necessário com a propriedade, graças ao wrapper de propriedade (@Binding), que cria os acessadores que tornam o .value desnecessário. Porém, com o parâmetro, não existe tal coisa e você tem que fazer isso explicitamente. Se você quiser saber mais sobre os wrappers de propriedade, verifique a sessão WWDC 415 - Modern Swift API Design e pule para 23:12.
Como você descobriu, modificar a variável @State do initilizer gerará o seguinte erro: Thread 1: Erro fatal: Accessing State outside View.body . Para evitá-lo, você deve remover o @State. O que faz sentido porque includeDecimal não é uma fonte de verdade. Seu valor é derivado da quantidade. Ao remover @State, no entanto, includeDecimal
não será atualizado se a quantidade mudar. Para isso, a melhor opção é definir seu includeDecimal como uma propriedade computada, de forma que seu valor seja derivado da fonte da verdade (quantidade). Dessa forma, sempre que o valor muda, seu includeDecimal também muda. Se sua visualização depende de includeDecimal, ela deve ser atualizada quando mudar:
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 { ... }
}
Conforme indicado por rob mayoff , você também pode usar $$varName
(beta 3) ou _varName
(beta4) para inicializar uma variável de estado:
$$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
deThread 1: Fatal error: Accessing State<Bool> outside View.body