I feel like I\'m missing something very basic, but this example SwiftUI code will not modify the view (despite the Binding updating) when the button is clicked
Tutorials
Looking into this some more I think I understand what's happening.
In this instance I want to use @Binding
as I'm building a custom control (like SwiftUI's native Toggle
, which also binds to a Bool
)
The issue is that the static state in ContentView_Previews
(i.e., the line @State static var selected: Bool = false
) does not trigger a re-render of the preview when the state changes, so even though the selected state has changed due to interaction with the control, the control (a child of ContentView_Previews
) does not re-render itself
This makes it tough to test controls in isolation in the SwiftUI preview, however moving the state into a dummy ObservableObject
instance functions correctly. Here's the code:
import SwiftUI
import Combine
class SomeData: ObservableObject {
@Published var isOn: Bool = false
}
struct MyButton: View {
@Binding var isSelected: Bool
var body: some View {
Button(action: {
self.isSelected.toggle()
}) {
Text(isSelected ? "Selected" : "Not Selected")
}
}
}
struct ContentView: View {
@EnvironmentObject var data: SomeData
var body: some View {
MyButton(isSelected: $data.isOn)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(SomeData())
}
}
It seems that a change in @State static var
doesn't trigger a preview re-render. In the above code my @Binding
example is moved into MyButton
and the content view's dummy environment instance is bounds to its isSelected
property. Tapping the button updates the view as expected in the SwiftUI preview.