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 I have read suggest this is the correct way to use a binding and the view should refresh automatically
import SwiftUI struct ContentView: View { @Binding var isSelected: Bool var body: some View { Button(action: { self.isSelected.toggle() }) { Text(isSelected ? "Selected" : "Not Selected") } } } struct ContentView_Previews: PreviewProvider { @State static var selected: Bool = false static var previews: some View { ContentView(isSelected: $selected) } }
You have not misunderstood anything. A View using a @Binding will update when the underlying @State change, but the @State must be defined within the view hierarchy. (Else you could bind to a publisher)
Below, I have changed the name of your ContentView to OriginalContentView and then I have defined the @State in the new ContentView that contains your original content view.
import SwiftUI struct OriginalContentView: View { @Binding var isSelected: Bool var body: some View { Button(action: { self.isSelected.toggle() }) { Text(isSelected ? "Selected" : "Not Selected") } } } struct ContentView: View { @State private var selected = false var body: some View { OriginalContentView(isSelected: $selected) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
SwiftUI View affects @Binding
. @State
affects SwiftUI View. @State
var affects the view, but to affect another @State
it must be used as binding by adding leading $
to value name and it works only inside SwiftUI.
To trigger SwiftUI change from outside, i.e. to deliver/update Image, use Publisher that looks like this:
// Declare publisher in Swift (outside SwiftUI). public let imagePublisher = PassthroughSubject<Image, Never>() // It must be handled within SwiftUI. struct ContentView: View { // Declare a @State that updates View. @State var image: Image = Image(systemName: "photo") var body: some View { // Use @State image declaration // and subscribe this value to publisher "imagePublisher". image.onReceive(imagePublisher, perform: { (output: Image) in self.image = output // Whenever publisher sends new value, old one to be replaced }) } } // And this is how to send value to update SwiftUI from Swift: imagePublisher.send(Image(systemName: "photo"))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With