如何在 SwiftUI 的列表视图中从 CoreData 延迟加载对象

问题描述 投票:0回答:1

在下面的代码中,我将

Categories
CoreData
加载到 SwiftUI 中的
List
视图中,但由于某种原因,加载时视图似乎有点慢。当对象显示在屏幕上时,延迟加载对象的最佳方法是什么?换句话说,我怎样才能加快加载时间。如果我将主
VStack
更改为
LazyVStack
,它不会显示任何类别。

如何在 SwiftUI 的列表视图中从 CoreData 延迟加载对象?

核心数据实体

类别
> 属性
>> 姓名
>> 图片

    class CategoryServiceModel: ObservableObject{
            
        let manager: CoreDataManager
        
        @Published var categories: [Category] = []  

        init(coreDataManager: CoreDataManager = .instance){
            self.manager = coreDataManager
            loadCategories()
        }

        func loadCategories(){
            let request = NSFetchRequest<Category>(entityName: "Category")

            let sort = NSSortDescriptor(keyPath: \Category.name, ascending: true)
            request.sortDescriptors = [sort]
            do{
                categories =  try manager.context.fetch(request)
                removeDuplicateCategoriesIfNeeded()
            }catch let error{
                print("Error fetching categories. \(error.localizedDescription)")
            }
        }
    }

    struct CategoriesView: View {
        @EnvironmentObject private var categorySM: CategoryServiceModel
        var body: some View {
            NavigationStack {
                VStack{ 
                    List{
                        ForEach(categorySM.categories, id:\.self) { category in
                                let image = UIImage(data: category.image ?? Data())
                                let imageSize: CGFloat = 35
                                HStack{
                                    if let inputImage = UIImage(data: category.image ?? Data()) {
                                        Image(uiImage: inputImage)
                                            .resizable()
                                            .aspectRatio(contentMode: .fit)
                                            .frame(width: imageSize, height: imageSize)
                                            .padding(10)
                                            .clipShape(Circle())
                                            .overlay(Circle().stroke(imageColor, lineWidth: 1))
                                    } 
                                    Text(category.name ?? "")
                                }
                            }
                        }
                    }
                }
            }
    }
swift swiftui core-data
1个回答
0
投票

List 本质上已经是惰性的。在 iOS 16-17 上它是一个 UICollectionView,在 iOS 15 上它是 UITableView。

列表之外的 VStack 和 LazyVStack 都不需要。 LazyVStack 包裹 List 时看不到内容的原因是它需要显式指定高度,并建议将 0 作为其子级的建议高度(VStack 进一步建议其所有父框架,因此您可以看到所有内容)。所以,List 认为它位于高度为 0 的框架内。您可以简单地通过向列表中添加具有显式高度的框架修改器来检查这一点,只需尝试假设 300。

所以,简而言之,List 本身就是一个惰性列表(UICollectionView),不要将其包装到任何堆栈中(除非您知道这样做的真正原因,但您的示例中并非如此)。

© www.soinside.com 2019 - 2024. All rights reserved.