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

SwiftUI中创建带@Binding参数的结构体及解决类型转换错误

解决SwiftUI中"Cannot convert value of type 'Bool' to expected argument type 'Binding'"错误

错误原因

你当前的写法存在两个核心问题:

  1. 直接给@Binding参数传普通Bool值:HabitEggButton的display是@Binding类型,它需要绑定到一个可变的状态源(比如@State/@ObservedObject属性),而非直接传入true这类常量值。
  2. 将View实例存入@State数组:SwiftUI的View是描述界面的结构体,应该由数据驱动渲染,不适合直接把View实例存储到状态数组中。

修复方案:数据与视图分离

正确的思路是把状态抽成独立的数据模型,让视图依赖数据渲染,具体步骤如下:

1. 创建数据模型

定义存储习惯信息的模型,实现Identifiable方便SwiftUI遍历:

struct Habit: Identifiable {
    let id = UUID()
    var habitName: String
    var display: Bool
}

2. 修改ContentView的状态存储

把原来的HabitEggButton数组替换为Habit数据模型数组,用@State管理:

struct ContentView: View {
    @State private var habits: [Habit] = [
        Habit(habitName: "Drink Water", display: true),
        Habit(habitName: "Gym", display: true),
        Habit(habitName: "Read a Book", display: true)
    ]
    
    var body: some View {
        VStack(spacing: 20) {
            // 遍历数据模型,传递状态绑定给视图
            ForEach($habits) { $habit in
                HabitEggButton(habitName: habit.habitName, display: $habit.display)
                    .onChange(of: habit.display) { isVisible in
                        // 长按隐藏后,从数组中移除对应项
                        if !isVisible {
                            habits.removeAll { $0.id == habit.id }
                        }
                    }
            }
        }
        .padding()
    }
}

3. 调整HabitEggButton视图

移除不必要的Identifiable实现(现在遍历的是数据模型),保留@Binding接收状态绑定:

import SwiftUI

struct HabitEggButton: View {
    var habitName: String
    @Binding var display: Bool
    
    var body: some View {
        Button(action: {
            print("\(habitName) button tapped")
            print(display ? "Yes" : "No")
        }) {
            Image("egg_uncracked")
                .resizable()
                .frame(width: 120, height: 120)
        }
        .supportsLongPress {
            display = false
            print("\(habitName) button held")
        }
    }
}

原理说明

  • 数据模型Habit存储所有可变状态,ContentView用@State管理整个数组的变化。
  • 通过$habit.display将状态绑定传递给HabitEggButton,长按修改display值后,onChange会触发数组过滤操作,移除已隐藏的项,实现界面自动重新渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 14:32:13