【问题标题】:How to sort List ForEach SwiftuiSwiftui 如何对 List ForEach 进行排序
【发布时间】:2023-01-11 16:59:22
【问题描述】:

你好呀

我是SwiftUI新手,想对expireDate进行排序,然后用forEach根据expireDate显示视图,怎么办???

对不起,我的代码很乱,编码真的不容易。

如果有人可以提供帮助,将不胜感激

这是数据

import Foundation

struct CardData: Identifiable, Codable {
    
    let id: UUID
    var cardName: String
    var cardNumber: String
    var expireDate: Date
    var theme: Theme
    var history: [History] = []
    
    init(id: UUID = UUID(), cardName: String, cardNumber: String, expireDate: Date, theme: Theme) {
        self.id = id
        self.cardName = cardName
        self.cardNumber = cardNumber
        self.expireDate = expireDate
        self.theme = theme
    }
}

extension CardData {
    struct Data {
        var cardName: String = ""
        var cardNumber: String = ""
        var expireDate: Date = Date.now
        var theme: Theme = .orange
    }
    var data: Data {
        Data(cardName: cardName, cardNumber: cardNumber, expireDate: expireDate, theme: theme)
    }
    
    mutating func update(from data: Data) {
        cardName = data.cardName
        cardNumber = data.cardNumber
        expireDate = data.expireDate
        theme = data.theme
    }
    
    init(data: Data) {
        cardName = data.cardName
        cardNumber = data.cardNumber
        expireDate = data.expireDate
        theme = data.theme
        id = UUID()
    }
}

这是视图

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 body: some View {
        List {
            ForEach($datas) { $data in
                NavigationLink(destination: DetailView(cardData: $data)){
                    CardDataView(cardData: data)
                }
                .listRowBackground(data.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)
    }
}

你好呀

我是SwiftUI新手,想对expireDate进行排序,然后用forEach根据expireDate显示视图,怎么办??? 对不起,我的代码很乱,编码真的不容易。 如果有人可以提供帮助,将不胜感激

【问题讨论】:

标签: sorting swiftui foreach binding


【解决方案1】:

ForEach中使用它之前,您可以对datas进行排序, 例如,当您创建 datas 时。像这样: datas.sort(by: { $0.expireDate > $1.expireDate})

或者

你可以在ForEach中对datas进行排序, 像这样,因为你有绑定, ForEach($datas.sorted(by: { $0.expireDate.wrappedValue > $1.expireDate.wrappedValue})) { $data ...}

注意这个ForEach($datas.sorted(by: ...),当你做你的func deleteItems(at offsets: IndexSet)时, 您将必须获取 sorted 数组中的索引,并删除原始数组中的等效项。

编辑-1:

更新func deleteItems

func deleteItems(at offsets: IndexSet) {
    let sortedArr = datas.sorted(by: { $0.expireDate > $1.expireDate})
    for ndx in offsets {
        if let cardIndex = datas.firstIndex(where: { $0.id == sortedArr[ndx].id }) {
            datas.remove(at: cardIndex)
        }
    }
}

【讨论】:

  • 非常感谢,看起来它有效,但是“当你执行 func deleteItems(at offsets: IndexSet) 时,你将不得不删除排序数组中的索引,而不是原始数组中的索引。”正如你所说,我该怎么办?
  • 如果我的回答对您有帮助,您能否将其标记为已接受,使用答案附近的勾号,它会变成绿色。
  • deleteItems代码更新了我的答案
猜你喜欢
  • 2017-11-02
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 1970-01-01
  • 2013-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多