【问题标题】:SwiftUI @Binding InitializeSwiftUI @Binding 初始化
【发布时间】:2019-11-03 06:33:44
【问题描述】:

到目前为止,我一直在使用 SwiftUI 并理解 BindableObjects 等的概念(至少我希望我这样做)。

我遇到了一个似乎无法找到答案的愚蠢问题: 如何初始化@Binding 变量?

我有以下代码:

struct LoggedInView : View {

    @Binding var dismissView: Bool

    var body: some View {
        VStack {
            Text("Hello World")
        }
    }
}

在我的预览代码中,我想传递Binding<Bool> 类型的参数:

#if DEBUG
struct LoggedInView_Previews : PreviewProvider {
    static var previews: some View {
        LoggedInView(dismissView: **Binding<Bool>**)
    }
}
#endif

我将如何初始化它?试过了:

Binding<Bool>.init(false)
Binding<Bool>(false)

甚至:

@Binding var dismissView: Bool = false

但没有一个有效...有什么想法吗?

【问题讨论】:

    标签: ios swift swiftui ios13


    【解决方案1】:

    当您在应用中使用LoggedInView 时,您确实需要提供一些绑定,例如来自先前视图的@State@EnvironmentObject

    对于 PreviewProvider 的特殊情况,您只需要一个固定值,您可以使用 .constant(false)

    例如

    #if DEBUG
    struct LoggedInView_Previews : PreviewProvider {
        static var previews: some View {
            LoggedInView(dismissView: .constant(false))
        }
    }
    #endif
    

    【讨论】:

    • 看起来很优雅。我只是想知道它是否使属性对于实时预览不可变。
    • 是的,但这通常是您预览所需的全部内容
    • 对于静态预览,使用不可变的 Binding.constant 很好,但对于我只想玩一个视图并查看值发生变化的实时预览来说,它完全不可用。
    • 下面@NeverwinterMoon 的解决方案更好,因为它可以让你与画布交互。
    【解决方案2】:

    使用Binding.constant(false) 很好,但仅适用于静态预览。如果您真的想启动实时预览,constant 的行为方式将与实际情况不同,因为它永远不会被您的操作更新。我个人经常使用实时预览,因为我可以玩一个孤立的视图。

    这是我为需要 Binding 的预览所做的:

    import SwiftUI
    
    struct SomeView: View {
       @Binding var code: String
    
       var body: some View {
         // some views modifying code binding
       }
    }
    
    struct SomeView_Previews: PreviewProvider {
      static var previews: some View {
        PreviewWrapper()
      }
    
      struct PreviewWrapper: View {
        @State(initialValue: "") var code: String
    
        var body: some View {
          SomeView(code: $code)
        }
      }
    }
    

    【讨论】:

    • 这行得通。但我想知道为什么添加像 @State static var code: String = "" 这样的属性还不够?
    • 这还不够,因为它不起作用,与建议的解决方案不同。使用 static var 属性值不会更新,它的工作方式与使用 Binding.constant 相同 - 仅适用于静态预览。
    • NeverwinterMoon 我在我的代码中使用了它,它就像一个魅力(我需要一个@State,因为我有一个 Binding 调用)。给了答案+1
    【解决方案3】:
    • 如果您需要一个属于单个视图的简单属性,您可以 应该使用 @State
    • 如果您需要复杂的属性,可能 属于您应该使用的多个视图(如 2-3 个视图) @ObjectBinding
    • 最后,如果您需要拥有需要使用所有周围视图的属性,您应该使用 @EnvironmentObject。 来源for detail information

    对于您的情况,如果您仍想初始化您的 Binding 变量,您可以使用:

    var binding: Binding = .constant(false)
    

    【讨论】:

      【解决方案4】:

      我在一个预览中使用了不同的视图配置(我正在开发一个自定义控件并希望看到它的不同配置)。我扩展了@NeverwinterMoon 提供的实现,以便创建视图的多个独立实例。

      struct SomeView: View {
         @Binding var value: Int
      
         var body: some View {
           // some views modifying code binding
         }
      }
      
      struct SomeView_Previews: PreviewProvider {
        static var previews: some View {
          VStack {
            // The same view but with different configurations
      
            // Configuration #1
            PreviewWrapper() { value in
              SomeView(value: value)
                .background(Color.blue)
            }
      
            // Configuration #2      
            PreviewWrapper(initialValue: 2) { value in
              SomeView(value: value)
                .padding()
            }
          }
        }
      
        struct PreviewWrapper<Content: View>: View {
          @State var value: Int
          private let content: (Binding<Int>) -> Content
          
          init(
            initialValue: Int = 0,
            @ViewBuilder content: @escaping (Binding<Int>) -> Content
          ) {
            self.value = initialValue
            self.content = content
          }
          
          var body: some View {
            content($value)
          }
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-07-14
        • 2020-11-10
        • 2021-09-26
        • 2019-11-20
        • 2020-10-24
        • 2020-03-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多