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

SwiftUI数组为何新增对象而非修改已有对象?

解决方法

你的代码存在两个核心问题,修正后就能实现仅修改指定元素字段的需求:

1. 数据模型错误使用@State

Row作为纯数据模型结构体,不需要用@State属性包装器——@State是SwiftUI用来标记视图内部需要管理的状态变量的,普通数据模型直接用常规属性即可:

struct Row: Identifiable {
    let id: Int // 用let保证id不被意外修改,符合Identifiable协议要求
    var lineBeginPos: CGFloat
    var lineEndPos: CGFloat
}

2. 编辑按钮的逻辑错误

你用rows.insert(...)是在数组索引0的位置插入新元素,这和你想要修改已有元素的需求完全相反。要修改索引0的lineEndPos,直接访问数组元素并更新对应字段即可,同时要先判断数组不为空,避免越界崩溃:

Button ("Edit/insert at index 0"){
    guard !rows.isEmpty else { return } // 数组为空时不执行操作
    rows[0].lineEndPos = 77
}

完整修正后的代码

import SwiftUI

struct Row: Identifiable {
    let id: Int
    var lineBeginPos: CGFloat
    var lineEndPos: CGFloat
}

struct ContentView: View {
    @State var txt: String = ""
    @State var rows: [Row] = []

    var body: some View {
        VStack {
            Text(txt)
            
            Button ("New append"){
                rows.append(Row(id: 0, lineBeginPos: 10, lineEndPos: 10 ))
                rows.append(Row(id: 1, lineBeginPos: 10, lineEndPos: 10 ))
            }
            
            Button ("Edit/insert at index 0"){
                guard !rows.isEmpty else { return }
                rows[0].lineEndPos = 77
            }
            
            Button ("Print array"){
                let arrayDesc = rows.description
                print("array: \(arrayDesc)")
                txt = "array: \(arrayDesc)"
            }
            
            Button ("remove all"){
                rows.removeAll()
                txt = ""
            }
        }
        .padding()
    }
}

现在点击编辑按钮时,就会直接修改数组中第一个元素的lineEndPos值,不会新增数组项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:12:13