xcode SwiftUI实时预览中的可变绑定

i1icjdpr  于 2023-02-05  发布在  Swift
关注(0)|答案(2)|浏览(98)

我有一个带有变量的ChildView:

@Binding var itemName: String

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

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

我试着像这样使用预览:

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

但我得到一个错误:
无法将类型“String”的值转换为预期的参数类型“Binding”
我知道我可以像下面这样使用预览。错误会消失,预览会正常工作,但是... itemName将具有常量值,它现在不会是可变的,在实时预览中不交互:

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

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

lpwwtiir

lpwwtiir1#

更新PreviewProvider中的@State变量似乎不会直接更新只读计算属性previews。解决方案是将@State变量 Package 在测试支架视图中。然后在previews属性中使用此测试视图,以便实时预览正确刷新。已在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()
    }
}
odopli94

odopli942#

如果您需要一个可以在实时预览中更改的值,我喜欢使用这个helper类:

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 {
        var yourVar = "example"
        BindingProvider(yourVar) { binding in
            YourView(initVar: binding)
        }
    }

}

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

相关问题