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

SwiftUI中按expireDate排序后用ForEach展示视图的实现方法

按过期日期排序CardData数组并展示的实现方法

核心思路

通过创建计算属性生成按expireDate排序后的数组,既不修改原数组的存储顺序,又能实现排序展示;同时通过元素的id匹配原数组绑定,保证编辑功能正常。

具体实现步骤

1. 添加排序后的计算属性

在CardView结构体内部添加只读计算属性,根据需求选择升序(最近过期的卡片在前)或降序(最远过期的卡片在前):

// 升序:最近过期的卡片排在最前面
var sortedDatas: [CardData] {
    datas.sorted { $0.expireDate < $1.expireDate }
}

// 可选:降序:最远过期的卡片排在最前面
// var sortedDatas: [CardData] {
//     datas.sorted { $0.expireDate > $1.expireDate }
// }

2. 修改ForEach绑定逻辑

遍历排序后的数组,通过元素id匹配原数组索引获取绑定对象,确保后续编辑功能不受影响:

List {
    ForEach(sortedDatas) { card in
        if let index = datas.firstIndex(where: { $0.id == card.id }) {
            NavigationLink(destination: DetailView(cardData: $datas[index])){
                CardDataView(cardData: card)
            }
            .listRowBackground(card.theme.mainColor)
        }
    }
    .onDelete(perform: deleteItems)
}

3. (可选)直接修改原数组顺序

如果不需要保留原始添加顺序,可以在onAppear中直接对原数组排序:

.onAppear {
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        launchScreenManager.dismiss()
    }
    // 升序排序原数组
    datas.sort { $0.expireDate < $1.expireDate }
}

这种方式更简洁,但会改变原数组的存储顺序。

完整修改后的CardView代码

import SwiftUI

struct CardView: View {
    
    @Binding var datas: [CardData]
    @Environment(\.scenePhase) private var scenePhase
    @State private var isPresentingNewCardView = false
    @State private var newCardData = CardData.Data()
    let saveAction: () -> Void
    @EnvironmentObject var launchScreenManager: LaunchScreenManager
    @State private var confirmationShow = false
    
    // 排序后的计算属性
    var sortedDatas: [CardData] {
        datas.sorted { $0.expireDate < $1.expireDate }
    }
    
    var body: some View {
        List {
            ForEach(sortedDatas) { card in
                if let index = datas.firstIndex(where: { $0.id == card.id }) {
                    NavigationLink(destination: DetailView(cardData: $datas[index])){
                        CardDataView(cardData: card)
                    }
                    .listRowBackground(card.theme.mainColor)
                }
            }
            .onDelete(perform: deleteItems)
        }
        .navigationTitle("Expiry Date")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            Button(action: {
                isPresentingNewCardView = true
            }) {
                Image(systemName: "plus")
            }
            .accessibilityLabel("New data")
        }
        .sheet(isPresented: $isPresentingNewCardView) {
            NavigationView {
                DetailEditView(data: $newCardData)
                    .toolbar {
                        ToolbarItem(placement: .cancellationAction) {
                            Button("Dismiss") {
                                isPresentingNewCardView = false
                                newCardData = CardData.Data()
                            }
                        }
                        ToolbarItem(placement: .confirmationAction) {
                            Button("Add") {
                                let newData = CardData(data: newCardData)
                                datas.append(newData)
                                isPresentingNewCardView = false
                                newCardData = CardData.Data()
                            }
                        }
                    }
            }
            
        }
        .onChange(of: scenePhase) { phase in
            if phase == .inactive { saveAction() }
        }
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                launchScreenManager.dismiss()
            }
        }
    }
    
    func deleteItems(at offsets: IndexSet) {
        datas.remove(atOffsets: offsets)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:10:26