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

SwiftUI带分组列表添加行问题(类UIKit的insertRowAtindexpath)

SwiftUI分组List添加行无效的问题及解决方法

需求是在SwiftUI的分组List中添加一行,模拟UIKit里insertRow(at:)的效果,但测试发现添加分组能正常触发UI更新,直接在分组内添加行却没有效果。

初始代码

import SwiftUI

struct TestList: View {
    
    @State var sections : [SectionModel] =
    [
        SectionModel(id: 1, rows:
                    [
                        RowModel(id: 1, name: "1"),
                             RowModel(id: 2, name: "2")
                    ]
               ),
        
        SectionModel(id: 2, rows:
                    [
                        RowModel(id: 1, name: "1"),
                        RowModel(id: 2, name: "2")
                    ]
               )
    ]
    
    var body: some View {
        List{
            ForEach (sections) { section  in
                Section(){
                    ForEach(section.rows) {row in
                        Button {
                            addRow() // 无效
                            addSection() // 有效
                        } label: {
                            Text(row.name)
                        }
                    }
                }
            }
        }
    }
    
    func addRow() {
        sections[0].addRow(row: RowModel.init(id: 10, name: "10"))
    }
    
    func addSection() {
        sections.append(SectionModel.init(id: 23, rows: [RowModel.init(id: 10, name: "10")]))
    }
}

class RowModel : Identifiable{
    var id: Int
    let name : String
    
    init(id: Int, name: String) {
        self.id = id
        self.name = name
    }
}

class SectionModel : Identifiable{
    var id  : Int
    var rows : [ RowModel]
 
    init(id: Int, rows:[ RowModel]) {
        self.id = id
        self.rows = rows
    }
    
    func addRow (row : RowModel) {
        rows.append(row)
    }
}

问题原因

SwiftUI的@State依赖值的变更触发UI刷新。当直接修改sections数组中某个SectionModel内部的rows数组时,sections数组本身的元素引用没有发生变化,@State检测不到数据源的变更,因此不会更新UI。而调用addSection()时,是给sections数组追加新元素,数组本身的结构发生了变化,所以能正常触发UI更新。

有效解决代码

修改addRow()方法,重新赋值对应的section对象,让@State检测到数组元素的变更:

func addRow() {
    var section = sections[0]
    section.addRow(row: RowModel.init(id: 10, name: "10"))
    sections[0] = section
}

总结

  • 直接修改ForEach数据源中的section对象(重新赋值)会触发UI更新
  • 仅修改section内部的row(二级元素)不会触发UI更新
  • 该问题与使用Struct或Class无关

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 09:47:38