SwiftUI - 反转布尔绑定

sna*_*rik 28 ios swift swiftui

我在 swiftUI 视图中有一个绑定。类似的东西:

struct MyCoolView: View { 
    @ObservedObject var viewModel: ViewModel

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

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

斯威夫特不会让我做类似的事情

.sheet(isPresented: !$viewModel.MyProperty) 
Run Code Online (Sandbox Code Playgroud)

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

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

E.C*_*oms 22

您可以自己构建绑定:

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

  • 小修正:在 `set` 中添加 `!`。即,`self.viewModel.MyProperty = !p`。 (3认同)

tge*_*ski 18

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

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

然后你可以不加任何修改地运行你的代码:

.sheet(isPresented: !$viewModel.MyProperty) 
Run Code Online (Sandbox Code Playgroud)

如果您不喜欢运算符,您可以在 Binding 类型上创建扩展:

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

然后做一些类似的事情:

.sheet(isPresented: $viewModel.MyProperty.not)
Run Code Online (Sandbox Code Playgroud)

甚至尝试使用全局 not 函数:

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

并像这样使用它:

.sheet(isPresented: not($viewModel.MyProperty))
Run Code Online (Sandbox Code Playgroud)


Clo*_*oud 10

根据 @E.Com 的回答,这是构建 的更短方法Binding<Bool>

Binding<Bool>(
    get: { !yourBindingBool },
    set: { yourBindingBool = !$0 }
)
Run Code Online (Sandbox Code Playgroud)