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

为何SwiftUI中toggle()函数与显式切换代码效果不一致?

SwiftUI中toggle()无法触发视图更新的问题

初始可运行代码

主文件

import SwiftUI

struct Home: View {
    @State private var ToDoItems: [ToDoItem] = [ToDoItem(title: "Task", description: "Need to do", urgent: false)]
    @State private var isAddingToDo: Bool = false
    
    var body: some View {
        VStack {
            
            ScrollView {
                ForEach(ToDoItems.indices, id: \.self) { index in
                    
                    HStack {
                        
                        Button {
                            if ToDoItems[index].done {
                                ToDoItems[index].done = false
                            } else {
                                ToDoItems[index].done = true
                            }
                        } label: {
                            if ToDoItems[index].done {
                                Image(systemName: "square.fill")
                            } else {
                                Image(systemName: "square")
                            }
                        }
                        
                        Text(ToDoItems[index].title)
                            .font(.title)
                    
                        
                    }
                    .padding()
                    
                }   
            }
            
        }
    }
}

ToDoItem 声明

import SwiftUI

struct ToDoItem: Identifiable {
    var title: String
    var createdAt: NSDate = NSDate()
    var id = UUID()
    var description: String
    var done = false
    var urgent: Bool
    init(title: String, description: String, done: Bool = false, urgent: Bool) {
        self.title = title
        self.description = description
        self.done = done
        self.urgent = urgent
    }
}

ToDoItem结构体中的done属性是默认值为false的布尔类型。

问题场景

将按钮点击事件的代码替换为使用toggle()后,视图不再更新:

原代码:

Button {
    if ToDoItems[index].done {
        ToDoItems[index].done = false
    } else {
        ToDoItems[index].done = true
    }
} label: {
    if ToDoItems[index].done {
        Image(systemName: "square.fill")
    } else {
        Image(systemName: "square")
    }
}

替换后的代码:

Button {
    ToDoItems[index].done.toggle()
} label: {
    if ToDoItems[index].done {
        Image(systemName: "square.fill")
    } else {
        Image(systemName: "square")
    }
}

明明toggle()的逻辑和手动赋值完全一致,为什么视图不会更新?

解决方法

在ToDoItem结构体中为done属性显式添加Bool类型声明后,问题解决。

更新后的ToDoItem声明

import SwiftUI

struct ToDoItem: Identifiable {
    var title: String
    var createdAt: NSDate = NSDate()
    var id = UUID()
    var description: String
    var done: Bool = false  // 更新行
    var urgent: Bool
    init(title: String, description: String, done: Bool = false, urgent: Bool) {
        self.title = title
        self.description = description
        self.done = done
        self.urgent = urgent
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:05:25