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

SwiftUI父子视图间三目运算符绑定Bool值报错求助

问题解决

错误原因分析

  1. Binding类型不匹配:你试图用!$colorOn对Binding<Bool>取反,但!运算符仅适用于Bool值,而非Binding包装类型,因此编译器报错。
  2. 重复触发状态切换:每个CircleView都绑定了定时器,导致每秒执行11次colorOn.toggle(),状态被反复抵消,实际不会产生预期的切换效果。

修正方案

方案一:简化参数类型(推荐)

由于CircleView仅需根据isOn值显示颜色,无需修改该状态,因此可以将子视图的@Binding改为普通Bool参数,直接传递计算后的布尔值即可:

struct ContentView: View {
    let timer = Timer.publish(every: 1.0, on: .main, in: .common).autoconnect()
    @State var colorOn = false
    
    var body: some View {
        VStack {
            ForEach(0...10, id: \.self) { n in
                // 直接传递计算后的Bool值,偶数位置跟随colorOn,奇数位置取反
                CircleView(size: 30, isOn: n % 2 == 0 ? colorOn : !colorOn)
            }
        }
        // 将定时器监听放在父视图,仅触发一次状态切换
        .onReceive(timer) { _ in
            colorOn.toggle()
        }
    }
}

#Preview {
    ContentView()
}

struct CircleView: View {
    var size: CGFloat
    var isOn: Bool // 替换@Binding为普通Bool参数

    var body: some View {
        Circle()
            .fill(isOn ? .red : .blue)
            .frame(width: size, height: size)
            .animation(.easeInOut(duration: 0.5), value: isOn)
    }
}

方案二:自定义Binding(适用于子视图需修改状态的场景)

如果后续需要让CircleView能修改父视图的状态,可以通过自定义Binding来实现取反逻辑:

struct ContentView: View {
    let timer = Timer.publish(every: 1.0, on: .main, in: .common).autoconnect()
    @State var colorOn = false
    
    var body: some View {
        VStack {
            ForEach(0...10, id: \.self) { n in
                CircleView(size: 30, isOn: n % 2 == 0 ? $colorOn : Binding(
                    get: { !self.colorOn },
                    set: { newValue in self.colorOn = !newValue }
                ))
            }
        }
        .onReceive(timer) { _ in
            colorOn.toggle()
        }
    }
}

struct CircleView: View {
    var size: CGFloat
    @Binding var isOn: Bool

    var body: some View {
        Circle()
            .fill(isOn ? .red : .blue)
            .frame(width: size, height: size)
            .animation(.easeInOut(duration: 0.5), value: isOn)
    }
}

效果说明

修正后,每隔1秒所有圆圈会同步切换颜色,且偶数位置的圆圈颜色与colorOn状态一致,奇数位置的圆圈颜色始终相反,符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:50:11