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

SwiftUI:使用ForEach展示排序数组时删除元素出现误删问题

问题根源

你遇到的删除错误,核心原因是界面显示的是排序后的新数组,但删除操作直接修改原数组:

  • records.sorted(by: <)会生成一个全新的排序后数组,它的元素索引和原movement.records完全不对应
  • 你用排序后数组的索引去删原数组的元素,自然会删错目标
解决方案

方法一:通过元素匹配删除(适配现有class模型)

  1. 先定义一个排序后的计算属性,避免重复排序:
var sortedRecords: [Record] {
    movement.records.sorted(by: <)
}
  1. 修改ForEach使用该计算属性:
ForEach(sortedRecords, id: \.self) { record in
    Text("\(record.date)")
}
.onDelete(perform: deleteRecord)
  1. 重写删除函数,通过引用匹配找到原数组中的目标元素:
func deleteRecord(_ indexSet: IndexSet) {
    for index in indexSet {
        let targetRecord = sortedRecords[index]
        // 用===匹配引用类型实例,找到原数组中的对应索引
        if let originalIndex = movement.records.firstIndex(where: { $0 === targetRecord }) {
            movement.records.remove(at: originalIndex)
        }
    }
}

方法二:改用struct模型(推荐,适配SwiftUI状态管理)

class是引用类型,用id: \.self容易引发状态不匹配问题,改成struct并实现Identifiable更符合SwiftUI设计:

  1. 修改Record模型:
struct Record: Comparable, Identifiable {
    let id = UUID() // 自动生成唯一标识
    var value: Float
    var date: Date
    
    init(value: Float = 0.0, date: Date = Date.now) {
        self.value = value
        self.date = date
    }
    
    static func < (lhs: Record, rhs: Record) -> Bool {
        return lhs.date < rhs.date
    }
}
  1. 同样定义排序后的计算属性,删除时通过id匹配:
var sortedRecords: [Record] {
    movement.records.sorted(by: <)
}

// ForEach可省略id参数(因为Identifiable)
ForEach(sortedRecords) { record in
    Text("\(record.date)")
}
.onDelete(perform: deleteRecord)

// 删除函数
func deleteRecord(_ indexSet: IndexSet) {
    let targetIds = indexSet.map { sortedRecords[$0].id }
    movement.records.removeAll { targetIds.contains($0.id) }
}

方法三:让原数组始终保持有序

如果业务逻辑允许,直接维护一个有序的原数组,这样界面和数据的索引完全对应:

  • 添加元素后立即排序:
func addRecord(_ record: Record) {
    movement.records.append(record)
    movement.records.sort(by: <)
}
  • ForEach直接使用原数组,删除函数无需修改:
ForEach(movement.records, id: \.self) { record in
    Text("\(record.date)")
}
.onDelete(perform: deleteRecord)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:57:56