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

为何SwiftUI中@State数组元素无法保留修改后的值?

SwiftUI中@State数组修改结构体元素值丢失问题解决

问题描述

在ContentView中声明了@State private var dice: [Die] = [Die.Example()],调用数组元素的Roll()方法时,仅在函数运行期间改变值,退出函数后元素立刻恢复初始状态。但同为@State变量的numDice修改后能正常保留值。

原因分析

Die是值类型结构体,在for var die in dice循环中,die是原数组元素的副本,调用die.Roll()只是修改了这个副本的属性,原数组中的元素完全没有被改动,所以循环结束后UI不会更新,看起来值丢失了。

解决方案

直接通过数组索引修改原数组中的元素,确保改动作用在原数据上:

修改Roll按钮的代码

把原来的循环替换为通过索引访问并修改原数组元素:

Button("Roll") {
    for index in dice.indices {
        dice[index].Roll()
    }
}

额外优化:修复UI布局问题

原代码中HStack里的ForEach同时包含DieView和List,会导致每个骰子都带一个列表,建议调整布局:

VStack {
    HStack {
        ForEach(dice) { die in
            DieView(dieValue: die.Value)
        }
    }
    
    // 把历史记录列表单独放在下方
    List(dice) { die in
        Section(header: Text("骰子\(die.id.uuidString.prefix(4))历史记录")) {
            ForEach(die.ValueHistory, id: \.self) { v in
                Text("\(v)")
            }
        }
    }
}

补充说明

如果后续Die的逻辑更复杂,也可以将Die改为ObservableObject类,数组声明为@State private var dice: [ObservedObject<Die>],但对于当前场景,直接通过索引修改值类型数组是更轻量的解决方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 12:35:28