【问题标题】:SwiftUI - Invert a boolean bindingSwiftUI - 反转布尔绑定
【发布时间】:2020-04-15 20:20:37
【问题描述】:

我在 swiftUI 视图中有一个绑定。类似于:

struct MyCoolView: View { 
    @ObservedObject var viewModel: ViewModel

    var body: some View { 
        Text("Here is a cool Text!").sheet(isPresented: $viewModel.MyProperty) { 
                            SomeModalView()}
        }
} 

我希望 isPresented 使用属性中存储的 相反 布尔值。

Swift 不会让我做类似的事情

.sheet(isPresented: !$viewModel.MyProperty) 

(它给了我一个关于无法将Binding <Bool> 转换为Bool 的错误)

关于如何处理这个问题的任何想法?

【问题讨论】:

  • 在将它发送到视图之前,您是否不能在视图模型中将其反转?还是我错过了什么?
  • 我应该更新并说,经过大约一年半的事后诸葛亮,并且对如何正确使用 Combine 和 publishers 有了更好的了解,您所建议的确实是正确的方法。我现在解决这个问题的方法是在存储在另一个已发布变量中的视图模型中创建对布尔值的订阅。我想时间会在 SO 上愚弄我们所有人。

标签: ios swift swiftui


【解决方案1】:

您可以自己构建绑定:

Text("Here is a cool Text!").sheet(isPresented:
         Binding<Bool>(get: {return !self.viewModel.MyProperty},
                       set: { p in self.viewModel.MyProperty = p})
          { SomeModalView()} } 

【讨论】:

  • 小修正:在set中添加!。即self.viewModel.MyProperty = !p.
【解决方案2】:

创建自定义前缀运算符怎么样?

prefix func ! (value: Binding<Bool>) -> Binding<Bool> {
    Binding<Bool>(
        get: { !value.wrappedValue },
        set: { value.wrappedValue = !$0 }
    )
}

然后你可以运行你的代码而无需任何修改:

.sheet(isPresented: !$viewModel.MyProperty) 

如果你不喜欢操作符,你可以在 Binding 类型上创建一个扩展:

extension Binding where Value == Bool {
    var not: Binding<Value> {
        Binding<Value>(
            get: { !self.wrappedValue },
            set: { self.wrappedValue = !$0 }
        )
    }
}

然后做类似的事情:

.sheet(isPresented: $viewModel.MyProperty.not)

甚至尝试全局非函数:

func not(_ value: Binding<Bool>) -> Binding<Bool> {
    Binding<Bool>(
        get: { !value.wrappedValue },
        set: { value.wrappedValue = !$0 }
    )
}

并像这样使用它:

.sheet(isPresented: not($viewModel.MyProperty))

【讨论】:

  • 你的意思是b in self.wrappedValue = !b,对吧?除了那个不错的答案:)
  • 实际上,当我在 setter 和 getter 中否定时,我会得到相同的结果(没有否定)。所以我们应该在 getter 或 setter 中取反,而不是在两个地方。不过,在 setter 中进行否定可能更直接。
  • 不,当您使用 setter 时,您的代码实际上会产生翻转的结果。如果将true 输入到setter,它会将value.wrappedValue 设置为true,而不是将否定绑定的值设置为true。尝试设置returnedBinding.wrappedValue = true,其中returnedBinding!anotherBinding 运算符的输出,你会看到如果你直接调用returnedBinding.wrappedValue,它将返回false 而不是true
  • @tgebarowski 非常好的扩展和功能,但需要一些修复。您应该反转设置的值,例如set: { value.wrappedValue = !$0 }
  • 扩展是完美的
【解决方案3】:

根据@E.Com 的回答,这是构造Binding&lt;Bool&gt; 的更短方法:

Binding<Bool>(
    get: { !yourBindingBool },
    set: { yourBindingBool = !$0 }
)

【讨论】:

    【解决方案4】:

    像这样添加扩展:

    extension Binding where Value == Bool {
        func negate() -> Bool {
            return !(self.wrappedValue)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-19
      • 1970-01-01
      • 1970-01-01
      • 2022-07-18
      • 1970-01-01
      • 2011-01-27
      • 2021-10-02
      相关资源
      最近更新 更多