SwiftUI 实时预览中的可变绑定

Posted

技术标签:

【中文标题】SwiftUI 实时预览中的可变绑定【英文标题】:Mutable Binding in SwiftUI Live Preview 【发布时间】:2019-12-09 10:27:13 【问题描述】:

我有一个带有变量的 ChildView:

@Binding var itemName: String

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

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

我试图像这样使用预览:

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

但我收到一个错误:

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

我知道我可以使用如下所示的预览。并且错误将消失并且预览将起作用,但是... itemName 将具有恒定值,它现在不会是可变的,在实时预览中不是交互式的:

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

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

【问题讨论】:

【参考方案1】:

更新PreviewProvider 中的@State 变量似乎不会直接更新只读计算属性previews。解决方案是将@State 变量包装在测试持有者视图中。然后在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()
    

【讨论】:

谢谢,Asperi,但它不起作用。没有错误,但 Live Preview 中的 itemName 仍然不是交互式的。我想是因为@Binding var itemName: String。我还更新了我的问题以显示我如何使用按钮来更改 itemName 的值。 我相信它以前有效......现在看起来@State 不再使previews 无效。已更新。【参考方案2】:

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

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)
        
    


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

【讨论】:

以上是关于SwiftUI 实时预览中的可变绑定的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 一新建

Xcode 11 - SwiftUI 预览暗模式 [重复]

Swiftui 无法分配给属性:'self' 是不可变的错误

如何修改 SwiftUI 预览的 UIView 属性?

SwiftUI中的快捷键积累

SwiftUI Xcode 11 beta 7 @Binding for collections 正在打破预览