SwiftUI 如何修改ListView选中状态的勾选图标 选中后UI不更新如何解决
问题根因
UI未同步刷新的核心原因有两点:
Todo是引用类型(Class),@State仅能监听值类型的整体变更,你修改Todo实例的completed属性时,items数组存储的元素引用没有发生变化,@State无法检测到变更,不会触发视图重绘。- 子视图
Row接收的item为不可变的let常量,没有内置的监听机制响应属性变更。
解决方案1:将Todo改为值类型(推荐)
绝大多数待办场景下用结构体更符合SwiftUI的设计理念,改动最小,性能最优:
// 将Todo从Class改为Struct struct Todo: Hashable { var title: String var completed: Bool } // 调整ContentView的遍历逻辑为绑定遍历 struct ContentView: View { @State var items: [Todo] = todoItems var body: some View { List($items) { $item in Row(item: item) { item.completed.toggle() print(item.completed) } } } } // 简化Row的回调逻辑 struct Row: View { let item: Todo var onTap: (() -> Void)? var body: some View { HStack { Image(systemName: item.completed ? "checkmark.square.fill" : "squareshape" ) .foregroundColor(item.completed ? .green : .gray) Text(item.title).font(.headline).foregroundColor(.secondary) }.onTapGesture { onTap?() } } } // 全局待办数据对应调整 let todoItems = [ Todo(title: "$300", completed: false), Todo(title: "$550", completed: false), Todo(title: "$450", completed: false) ]
解决方案2:保留Class的适配方案
如果业务必须保留Todo为Class类型,需要搭配SwiftUI的对象监听协议实现刷新:
// Todo遵循ObservableObject协议,需要监听的属性加@Published注解 class Todo: Hashable, ObservableObject { static func == (lhs: Todo, rhs: Todo) -> Bool { lhs.title == rhs.title } var title: String @Published var completed: Bool init(title: String, completed: Bool) { self.title = title self.completed = completed } func hash(into hasher: inout Hasher) { hasher.combine(title) } } // Row用@ObservedObject接收Todo实例,监听属性变更 struct Row: View { @ObservedObject var item: Todo var onTap: (() -> Void)? var body: some View { HStack { Image(systemName: item.completed ? "checkmark.square.fill" : "squareshape" ) .foregroundColor(item.completed ? .green : .gray) Text(item.title).font(.headline).foregroundColor(.secondary) }.onTapGesture { onTap?() } } } // ContentView无需额外调整 struct ContentView: View { @State var items: [Todo] = todoItems var body: some View { List(items, id: \.self) { item in Row(item: item) { item.completed.toggle() print(item.completed) } } } }
内容的提问来源于stack exchange,提问作者Jessy
相关产品推荐
相关产品推荐

