Create a mutable @Binding in SwiftUI Previews
August 11, 2020If you played a little bit with SwiftUI chances are you may have wondered about one thing in preview: how to make a real @Binding
that can be modified?
struct TalkDetail_Previews: PreviewProvider {
struct var previews: some View {
TalkDetail(.constant(Preview.sampleTalk)) // I'm able to make a Binding but actions won't take effect
}
}
.constant
is not what we are looking for here as we want to make modifications to the data. Binding(get:set:)
might not be a good fit either: it won't trigger any state update and so no view update. The trick here is to make a in-between view which will store our data and send it back to the view we are testing:
/// Store a (writable) binding transferred to underlying content
struct WithBinding<T, Content: View>: View {
@State private var data: T
private let content: (Binding<T>) -> Content
init(for data: T, @ViewBuilder content: @escaping (Binding<T>) -> Content) {
self.data = data
self.content = content
}
var body: some View {
content($data)
}
}
You can now change your preview and have your binding working as expected 🚀
struct TalkDetail_Previews: PreviewProvider {
static var previews: some View {
WithBinding(for: Preview.sampleTalk)Â {
TalkDetail($0)
}
}
}