Estou tentando criar um costume ButtonStyle
que responda a mudanças de estado. Não consigo atualizá-lo quando o estado muda.
Aqui está uma versão simplificada:
struct TestButton: ButtonStyle {
@State var selected: Bool = true
func makeBody(configuration: ButtonStyleConfiguration) -> some View {
configuration.label
.frame(width: 48)
.padding(EdgeInsets(top: 3, leading: 4, bottom: 3, trailing: 4))
.background(selected ? .green : .red)
.cornerRadius(14)
}
}
struct TestView: View {
@AppStorage("test") var test = 1
var body: some View {
HStack {
Button(test == 1 ? "Yes" : "No") { test = 1 }
.buttonStyle(TestButton(selected: test == 1))
Button(test == 2 ? "Yes" : "No") { test = 2 }
.buttonStyle(TestButton(selected: test == 2))
Button(test == 3 ? "Yes" : "No") { test = 3 }
.buttonStyle(TestButton(selected: test == 3))
}
// .id(UUID()) // trying to avoid this
.padding()
}
}
A variável test
é definida pelos botões, e eu quero que ela altere a aparência do botão. O teste test == …
funciona corretamente, pois o texto alterna entre Yes
e No
. No entanto, quando eu o uso com o selected
parâmetro, ele não altera nada. Ele define o valor quando a visualização é carregada pela primeira vez, mas não atualiza.
A variável na exibição usa @AppStorage
, mas tentei com @State
e obtive os mesmos resultados.
Sei que posso fingir adicionando .id(UUID())
, mas não tenho certeza se é a melhor abordagem.
Como posso atualizar o ButtonStyle
?
Basta definir
selected
ser uma propriedade normal. Aqui está um exemplo, eu apenas altero@AppStorage
para um@State
para facilitar o teste:Ao usar
@State var selected
emButtonStyle
, ele apenas recebe o valor quando uma identidade é criada, adicionando.id(UUID())
trabalho porque faz com que o ButtonStyle atual seja destruído e um novoIdentity
seja criado, portanto,ButtonStyle
receberáselected
a mudança. Recomendo que você assista "Demystify SwiftUI" para entender melhor.