SwiftUI @Binding update doesn't refresh view

前端 未结 5 2033
一个人的身影
一个人的身影 2021-02-19 21:31

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

5条回答
  •  不思量自难忘°
    2021-02-19 22:00

    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.

提交回复
热议问题