【问题标题】:SwiftUI - Indexset to index in arraySwiftUI - 在数组中索引的索引集
【发布时间】:2020-05-09 02:42:06
【问题描述】:

我在 NavigationView 和列表中使用 ForEach,并结合了当用户使用 .onDelete() 删除行时调用的函数,如下所示。

struct PeriodListView: View {
@ObservedObject var theperiodlist = ThePeriodList()
@EnvironmentObject var theprofile: TheProfile

@State private var showingAddPeriod = false

var dateFormatter: DateFormatter {
    let formatter = DateFormatter()
    formatter.dateStyle = .long
    return formatter
}

var body: some View {
    NavigationView {
        List {
            ForEach(theperiodlist.periods) {period in
                PeriodRow(period: period)
            }
            .onDelete(perform: removePeriods)
        }
        .navigationBarTitle("Periods")
            .navigationBarItems(trailing:
                Button(action: {self.showingAddPeriod = true}) {
                    Image(systemName: "plus")
                }
            )
        .sheet(isPresented: $showingAddPeriod) {
            AddPeriod(theperiodlist: self.theperiodlist).environmentObject(self.theprofile)
        }
    }
}
func removePeriods(at offsets: IndexSet) {
    AdjustProfileRemove(period: theperiodlist.periods[XXX])
    theperiodlist.periods.remove(atOffsets: offsets)
}

我有一个单独的函数 (AdjustProfileRemove(period)),我想用删除的句点作为变量来调用它 - 例如我想在 AdjustProfileRemove(period: theperiodlist.periods[XXX]) 中找到 XXX。有没有一种简单的方法可以做到这一点(我从 IndexSet 猜测)还是我错过了一些基本的东西?

谢谢。

【问题讨论】:

  • 我有点不清楚你在问什么。您能否概述一下AdjustProfileRemove(_ : Period) 函数?
  • 我刚开始使用 SwiftUI 并尝试构建我的第一个项目。 AdjustProfileRemove(_ : Period) 函数将 Period() 作为输入(它们是 theperiodlist.periods-list 中的元素)并返回一组我想要使用的整数。所以我正在寻找当用户从 NavigationView 中删除特定 Period() 时获得的 theperiodlist.periods-list 的索引。我希望这可以澄清?

标签: arrays swift swiftui


【解决方案1】:

.onDelete 被声明为

@inlinable public func onDelete(perform action: ((IndexSet) -> Void)?) -> some DynamicViewContent

IndexSet 只是数组中要删除的元素的所有索引的 Set。让我们试试这个例子

var arr = ["A", "B", "C", "D", "E"]
let idxs = IndexSet([1, 3])

idxs.forEach { (i) in
    arr.remove(at: i)
}
print(arr)

所以生成的 arr 现在是

["A", "C", "D"]

.onDelete之所以使用IndexSet,是因为可以选择List中的多行进行删除操作。

小心!查看结果数组!实际上一个一个地删除元素需要一些逻辑......

我们试试

var arr = ["A", "B", "C", "D", "E"]
let idxs = IndexSet([1, 3])

idxs.sorted(by: > ).forEach { (i) in
    arr.remove(at: i)
}
print(arr)

它现在可以按您的预期工作,是吗?现在的结果是

["A", "C", "E"]

基于

theperiodlist.periods.remove(atOffsets: offsets)

看来,ThePeriodList 已经具有所需功能的内置功能。

在你的情况下,只需替换

AdjustProfileRemove(period: theperiodlist.periods[XXX])

offsets.sorted(by: > ).forEach { (i) in
    AdjustProfileRemove(period: theperiodlist.periods[i])
}

【讨论】:

  • 感谢您的宝贵意见。没有意识到 IndexSet 可以包含多个索引。我使用了上面 Asperi 提出的解决方案。
  • @user3612450 由您决定。我看到 Asperi 的解决方案过于复杂,可以通过代码库中的两行代码来完成 :-)。重要的是,你已经明白了。
  • @user3612450 我更新了我的答案如何在你的代码中使用它
【解决方案2】:

这是可能的方法(考虑到一般offsets 可以包含许多索引)

func removePeriods(at offsets: IndexSet) {
    theperiodlist.periods = 
        theperiodlist.periods.enumerated().filter { (i, item) -> Bool in
            let removed = offsets.contains(i)
            if removed {
                AdjustProfileRemove(period: item)
            }
            return !removed
        }.map { $0.1 }
}

【讨论】:

    猜你喜欢
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    相关资源
    最近更新 更多