在SwiftUI Live Preview中绑定(可变)

时间:2019-12-09 10:27:13

标签: swift xcode swiftui

我有一个带有变量的ChildView:

@Binding var itemName: String

在此ChildView中,我只有几个按钮可以更改变量的值:

Button(action: {
    self.itemName = "different value"
})

我试图像这样使用Preview:

struct ChildView_Previews: PreviewProvider {
    static var previews: some View {
        ChildView(itemName: "test")
    }
}

但是我遇到一个错误:

  

无法将“字符串”类型的值转换为预期的参数类型   “绑定”

我知道我可以像下面那样使用Preview。而且错误将消失并且预览将正常工作,但是... itemName将具有恒定值,现在将不再可变,在Live Preview中不可交互:

struct ChildView_Previews: PreviewProvider {
    static var previews: some View {
        ChildView(itemName: .constant("test"))
    }
}

如何在SwiftUI预览中声明绑定以使其具有交互性?

2 个答案:

答案 0 :(得分:1)

如果您需要一个可以在实时预览中更改的值,我喜欢使用此帮助程序类:

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)
        }
    }

}

这使您可以测试更改实时预览中的绑定。

答案 1 :(得分:0)

更新:出现的@State不会直接更新previews,因此,想法是将测试视图包装到@State提供程序中,以刷新预览视图。经过在Xcode 11.2.1上的测试。

struct ChildView: View {
    @Binding var itemName: String

    var body: some View {
        VStack {
            Text("Name: \(itemName)")
            Button(action: {
                self.itemName = "different value"
            }) {
                Text("Change")
            }
        }
    }
}

struct ChildView_Previews: PreviewProvider {

    struct BindingTestHolder: View {
        @State var testItem: String = "Initial"
        var body: some View {
            ChildView(itemName: $testItem)
        }
    }

    static var previews: some View {
        BindingTestHolder()
    }
}