SwiftUI列表的性能问题

时间:2020-01-05 22:28:43

标签: swift swiftui swiftui-list

我有一个列表,其中显示了动态FetchRequest的结果。

代码工作正常,但是结果集更大(例如3000),因此在动态谓词发生更改时,列表的建立速度非常慢。

struct ItemList: View {
    @State var startsWith: String = "A"

    var body: some View {
        NavigationView {
            VStack {
                TextField("Startswith", text:$startsWith)
                FilterRequestList(filter: startsWith)
            }
            .navigationBarTitle("Tasks CD")
        } 
    }
} 


struct FilterRequestList: View {
    var fetchRequest: FetchRequest<Item>

    init(filter: String) {
        if filter == "" {
            fetchRequest = FetchRequest<Item>(entity: Item.entity(),
                                              sortDescriptors: [],
                                              predicate: nil)
        } else {
            fetchRequest = FetchRequest<Item>(entity: Item.entity(),
                                              sortDescriptors: [],
                                              predicate: NSPredicate(format: "title BEGINSWITH %@", filter))
        }
    }

    var body: some View {
        VStack {
            Text("Count: \(fetchRequest.wrappedValue.count)")
            List(fetchRequest.wrappedValue, id: \.self) { item in
                Text("\(item.title) ")
            }
        }
    }
}

任何想法,如何改进?

更新: 我发现: 第一个List相当快,但是如果startsWith State改变了,重装就很慢。 我加了

FilterRequestList(filter: startsWith)
    .onAppear(perform: { print("appear F") })
    .onDisappear(perform: { print("disappear F") })

并发现,FilterRequestList并没有在过滤器更换时消失并重新出现。

可能是问题吗?如何强制娱乐?

1 个答案:

答案 0 :(得分:0)

感谢Paul Hudson,我找到了解决问题的方法。 他在“ https://www.youtube.com/watch?v=h0SgafWwoh8”中对其进行了详细说明。

您只需添加修饰符

.id(UUID())

到列表。

问题是,swiftUI尝试检测从旧列表到新列表的任何更改以使更改动起来。 使用修改器,swiftUI的旧列表和新列表是不相同的列表(由于ID一直在变化),因此无需检测更改。 Swift可以轻松快速地创建新列表。 唯一的遗憾是,因此没有动画。

struct ItemList: View {
    @State var startsWith: String = "A"

    var body: some View {
        NavigationView {
            VStack {
                TextField("Startswith", text:$startsWith)
                FilterRequestList(filter: startsWith)
            }
            .navigationBarTitle("Tasks CD")
        } 
    }
} 


struct FilterRequestList: View {
    var fetchRequest: FetchRequest<Item>

    init(filter: String) {
        if filter == "" {
            fetchRequest = FetchRequest<Item>(entity: Item.entity(),
                                              sortDescriptors: [],
                                              predicate: nil)
        } else {
            fetchRequest = FetchRequest<Item>(entity: Item.entity(),
                                              sortDescriptors: [],
                                              predicate: NSPredicate(format: "title BEGINSWITH %@", filter))
        }
    }

    var body: some View {
        VStack {
            Text("Count: \(fetchRequest.wrappedValue.count)")
            List(fetchRequest.wrappedValue, id: \.self) { item in
                Text("\(item.title) ")
            }
            .id(UUID())
        }
    }
}