SwiftUI和CoreData - 有序列表

4

我正在尝试在SwiftUI中使用CoreData记录创建有序列表。如何在这样的列表中打印连续数字?

在下面的示例中,我有一个名为SomeEntity的实体,其中有一个名为title的String属性。

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!)
               }
           }
           }


         }
      }
   }
}

“Running numbers”是什么意思?是指“序号”吗? - Asperi
Text("\(item.id)") 可以吗? - iSpain17
是的,只需1.itemName、2.itemName、3.itemName。倒序更好:3,2,1。我在想能否从每个实体实例中获得索引。或者使用计数和-1来获取每个下一个实例。但我找不到一个可行的例子。 - mallow
3个回答

4

也许你需要像以下这样的东西

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的第二个答案以获取反向顺序。 - mallow
2
对于反转,请使用 enumerated().reversed() - Asperi
它能工作,但是当.fetchBatchSize = 10请求时会出现问题,所以请考虑这一点。 - Michał Ziobro

0

我已经测试过了,使用@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使得在滚动时获取额外的项目成为可能。


0
根据您的评论,这应该可以工作:您需要使用不同的ForEachinit,它将Range<Int>作为第一个参数。
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的答案已经解决了这个问题。 - mallow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接