为何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
相关产品推荐
相关产品推荐

