具有@Binding可选属性的SwiftUI View的初始化似乎不明确

时间:2019-10-03 11:53:15

标签: ios swift swiftui

基于下面的代码,我的假设是:

  • $a返回一个Binding<Bool>
  • Binding.constant(a: self.a)还返回Binding<Bool>

那为什么B(a: Binding<Bool?>)拒绝(正确)使用"Cannot convert value of type 'Binding<Bool>' to expected argument type 'Binding<Bool?>'"的第一个,却接受第二个?

import SwiftUI

struct ContentView: View {
    @State var a: Bool = false

    var body: some View {
        A(a: $a)
    }
}

struct A : View {
    @Binding var a: Bool

    var body: some View {
            //B(a: $a)
            // ^~~~ 
            // Fails with "Cannot convert value of type 'Binding<Bool>' to expected argument type 'Binding<Bool?>'"       
            B(a: Binding.constant(self.a))
    }
}

struct B : View {
    @Binding var a: Bool?

    var body: some View {

        if a == nil {
            return Text("a is nil")
        } else {
            return Text("a is \(a! ? "true" : "false")")
        }
    }
}

1 个答案:

答案 0 :(得分:1)

如果有人将Bool中的派生可选Bool绑定设置为A.a,那么B.b所持有的非可选nil的内容会发生什么变化?将Bool包裹在.constant中的解决方法行之有效,因为它可以防止这种可能性(因为无法更改常量绑定)。

您也可以创建一个派生的绑定,该绑定仅忽略设置nil的值,就像这样(请注意,用于指定基础属性包装器值的未公开文档的“ _”前缀):

extension B {
    init(reqA: Binding<Bool>) {
        self._a = Binding<Bool?>(get: { reqA.wrappedValue },
          set: { if let newValue = $0 { reqA.wrappedValue = newValue } })
    }
}