SwiftUI 如何在 View 需要初始化器中的 @Binding 时实例化 PreviewProvider

SwiftUI How to instantiate PreviewProvider when View requires @Binding in initializer

使用 SwiftUI (Xcode 11.1),我已经为一些视图设置了双向绑定(使用 @Binding)。双向更新效果很好。

但是,如何从 PreviewProvider 实例化视图?

例如:

struct AddProjectView: View {

    @Binding public var showModal: Bool

    var body: some View {

        return VStack {
            Text("Add Project View")
            Button("Dismiss") {
                self.showModal = false
            }
        }
    }
}

我不能这样做,因为 "true" 不是绑定:

struct AddProjectView_Previews: PreviewProvider {
    static var previews: some View {
        AddProjectView(showModal: true)
    }
}

我不能这样做,因为“属性 本地属性尚不支持包装器”:

struct AddProjectView_Previews: PreviewProvider {
    static var previews: some View {
        @Binding var show = true
        return AddProjectView(showModal: $show)
    }
}

我们如何做到这一点?

谢谢!!

您必须在预览中将其声明为@State。

struct AddProjectView_Previews: PreviewProvider {

     @State static var showModal: Bool = false

     static var previews: some View {
         AddProjectView(showModal: $showModal)
     }
}

还请记住,它需要是静态的,因为它在静态函数中使用。

.constant 正是为了这个:

/// Creates a binding with an immutable value.

struct AddProjectView: View {
    @Binding public var showModal: Bool
    var body: some View {
        return VStack {
            Text("Add Project View")
            Button("Dismiss") {
                self.showModal = false
            }
        }
    }
}

struct AddProjectView_Previews: PreviewProvider {
    static var previews: some View {
        AddProjectView(showModal: .constant(true))
    }
}

如果你只需要一个常量值,使用.constant(VALUE):

struct YourView_Previews: PreviewProvider {

    static var previews: some View {
        YourView(yourBindingVar: .constant(true))
    }

}

如果你需要一个可以在实时预览中更改的值,我喜欢用这个助手class:

struct BindingProvider<StateT, Content: View>: View {

    @State private var state: StateT
    private var content: (_ binding: Binding<StateT>) -> Content

    init(_ initialState: StateT, @ViewBuilder content: @escaping (_ binding: Binding<StateT>) -> Content) {
        self.content = content
        self._state = State(initialValue: initialState)
    }

    var body: some View {
        self.content($state)
    }
}

像这样使用它:

struct YourView_Previews: PreviewProvider {

    static var previews: some View {
        BindingProvider(false) { binding in
            YourView(yourBindingVar: binding)
        }
    }

}

这允许您在实时预览中测试更改绑定。