【问题标题】:SwiftUI & CoreData - ordered listSwiftUI & CoreData - 有序列表
【发布时间】:2023-03-30 21:20:02
【问题描述】:

我正在尝试使用 CoreData 记录在 SwiftUI 中创建一个有序列表。 如何在这样的列表中打印流水号?

在以下示例中,我有一个名为 SomeEntity 的实体,其字符串属性名为 title

import SwiftUI
struct ContentView: View {

   var fetchRequest: FetchRequest<SomeEntity>
   var items: FetchedResults<SomeEntity> { fetchRequest.wrappedValue }

   var body: some View {
      NavigationView {
         List {

            ForEach(items, id: \.self) {item in

            NavigationLink(destination: ItemDetailsView(item: item)) {

                HStack {
                    Text("99")
                    // How to print running number instead of "99" in this ordered list of CoreData records?
                    // I was thinking about something like this:
                    // Text(items.id) - but this doesn't work. Is there something similar?
                        .multilineTextAlignment(.center)
                        .frame(width: 60)
                    Text(item.title!)
               }
           }
           }


         }
      }
   }
}

【问题讨论】:

  • 你所说的“连续数字”是什么意思?是“序数”吗?
  • Text("\(item.id)") 也许?
  • 是的,只有 1.itemName、2.itemName、3.itemName。颠倒顺序会更好:3,2,1。我在想我可以从实体的每个实例中获取索引。或者对每个下一个实例使用计数和 -1。但我找不到工作示例

标签: ios swift list core-data swiftui


【解决方案1】:

可能你需要类似下面的东西

struct ContentView: View {

   var fetchRequest: FetchRequest<SomeEntity>
   var items: FetchedResults<SomeEntity> { fetchRequest.wrappedValue }

   var body: some View {
      NavigationView {
         List {

            ForEach(Array(items.enumerated()), id: \.element) {(i, item) in

            NavigationLink(destination: ItemDetailsView(item: item)) {

                HStack {
                    Text("\(i + 1)")
                        .multilineTextAlignment(.center)
                        .frame(width: 60)
                    Text(item.title!)
               }
           }
           }
         }
      }
   }
}

【讨论】:

  • 完美!它适用于不断增长的数字。我将检查 iSpain17 的第二个答案以获得相反的顺序。
  • 反向使用enumerated().reversed()
  • 它可以工作,但会中断 .fetchBatchSize = 10 个请求,因此请考虑到这一点
【解决方案2】:

根据您的 cmets,这应该有效:您需要使用不同的 initForEach,它将 Range&lt;Int&gt; 作为第一个参数:

ForEach(-items.count..<0, id: \.self) { i in 
    NavigationLink(destination: ItemDetailsView(item: items[-i])) {
        HStack {
            Text("\(items[-i].itemName)")
                .multiLineTextAlignment(.center)
                .frame(width: 60)
            Text("\(items[-i].title!)")
        }
    }
}

-items.count0 也确保了相反的顺序。

【讨论】:

  • 感谢您帮助我,iSpain17。我的代码几乎没有问题 - 也许我犯了一些错误并且没有正确实施。但是 Asperi 的回答已经解决了这个问题。
【解决方案3】:

我已经对其进行了测试,使用 @FetchRequest 这个解决方案似乎是最好的。

 List {

        ForEach(self.contacts.indices, id: \.self) { i in


            Button(action: {
                self.selectedId = self.contacts[i].id!
            }) {

                ContactRow(contact: self.contacts[i])
                    .equatable()
                    .background(Color.white.opacity(0.01))
            }
            .buttonStyle(ListButtonStyle())
            .frame(height: 64)  
            .listRowBackground( (i%2 == 0) ? Color("DarkRowBackground") : .white)
            .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
        }
    }

我还测试了 Array(self.contacts.enumerated()) 的解决方案,但效果不佳。如果你有少量的记录,它可以是好的,但对于大量的记录,它是次优的。

如果你使用

request.fetchBatchSize = 10

滚动列表时批量加载记录(实体) enumerated() 不起作用执行所有需要的 SELECT ... LIMIT 10 个请求一次

.indices 可以在滚动时获取其他项目。

【讨论】:

    猜你喜欢
    • 2022-01-20
    • 2019-12-23
    • 2021-12-24
    • 2021-10-09
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多