You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何创建与同一变量反向绑定的Toggle?

SwiftUI实现绑定同一变量的反向Toggle按钮

我想创建一个包含两个Toggle按钮的视图,它们绑定同一个布尔变量,但其中一个Toggle的状态是该变量的反向——只有当原变量为false时,这个Toggle才处于选中状态。

之前的错误尝试

尝试1:直接用感叹号反转绑定

最初我尝试直接在绑定变量前加感叹号反转:

Toggle(isOn: $myStruct.myBooleanVar) {
    Text("Yes").frame(width: 80)
}.toggleStyle(.button)
Toggle(isOn: $myStruct.!myBooleanVar) {
    Text("no").frame(width: 80)
}.toggleStyle(.button)

结果报错:

'.!' is not a binary operator

尝试2:寻找反转修饰符

之后我想找有没有能反转Toggle状态的修饰符,尝试这样写:

Toggle(isOn: $myStruct.myBooleanVar) {
    Text("Yes").frame(width: 80)
}.toggleStyle(.button)
Toggle(isOn: $myStruct.myBooleanVar) {
    Text("no").frame(width: 80)
}.toggleStyle(.button)
.inverted(true)

但SwiftUI里并没有这类修饰符。

尝试3:使用临时变量/自定义绑定

接着我尝试用临时变量、状态变量或者自定义绑定来实现,但都遇到同一个报错:

Cannot use instance member 'settings' within property initializer; property initializers run before 'self' is available

正确实现方式

要实现反向绑定,核心是手动创建Binding<Bool>,通过get和set方法反转值,同时避开属性初始化器中无法引用self的问题,以下是几种可行方案:

方案1:在body里创建自定义绑定

直接在视图的body中定义反向绑定,避开初始化阶段的self问题:

struct ContentView: View {
    @State private var myStruct = MyStruct(myBooleanVar: false)
    
    var body: some View {
        // 定义反向绑定
        let reversedBinding = Binding<Bool>(
            get: { !self.myStruct.myBooleanVar },
            set: { self.myStruct.myBooleanVar = !$0 }
        )
        
        HStack {
            Toggle(isOn: $myStruct.myBooleanVar) {
                Text("Yes").frame(width: 80)
            }.toggleStyle(.button)
            
            Toggle(isOn: reversedBinding) {
                Text("No").frame(width: 80)
            }.toggleStyle(.button)
        }
    }
}

struct MyStruct {
    var myBooleanVar: Bool
}

方案2:用计算属性封装反向绑定

如果需要多次使用反向绑定,可以把它封装成视图的计算属性:

struct ContentView: View {
    @State private var myStruct = MyStruct(myBooleanVar: false)
    
    // 封装反向绑定为计算属性
    private var reversedMyBoolean: Binding<Bool> {
        Binding(
            get: { !myStruct.myBooleanVar },
            set: { myStruct.myBooleanVar = !$0 }
        )
    }
    
    var body: some View {
        HStack {
            Toggle(isOn: $myStruct.myBooleanVar) {
                Text("Yes").frame(width: 80)
            }.toggleStyle(.button)
            
            Toggle(isOn: reversedMyBoolean) {
                Text("No").frame(width: 80)
            }.toggleStyle(.button)
        }
    }
}

方案3:扩展Binding实现通用反转

给Binding<Bool>写个扩展,让所有布尔绑定都能直接调用反转方法:

// 扩展Binding,添加反转功能
extension Binding where Value == Bool {
    var reversed: Binding<Bool> {
        Binding(
            get: { !self.wrappedValue },
            set: { self.wrappedValue = !$0 }
        )
    }
}

// 使用示例
struct ContentView: View {
    @State private var myStruct = MyStruct(myBooleanVar: false)
    
    var body: some View {
        HStack {
            Toggle(isOn: $myStruct.myBooleanVar) {
                Text("Yes").frame(width: 80)
            }.toggleStyle(.button)
            
            // 直接调用.reversed获取反向绑定
            Toggle(isOn: $myStruct.myBooleanVar.reversed) {
                Text("No").frame(width: 80)
            }.toggleStyle(.button)
        }
    }
}

内容的提问来源于stack exchange,提问作者SwiftlySlow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 22:10:35