swift - SwiftUI 列表的性能问题
问题描述
我有一个显示动态 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 状态发生变化,重新加载非常慢。我添加了
FilterRequestList(filter: startsWith)
.onAppear(perform: { print("appear F") })
.onDisappear(perform: { print("disappear F") })
并发现,FilterRequestList
当过滤器改变时,它并没有消失和重新出现。
这可能是问题吗?怎么可以强迫消遣?
解决方案
感谢 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())
}
}
}
推荐阅读
- apache-spark - PySpark:结合聚合和窗口函数
- flutter - Flutter:可以将 CupertinoPicker 中的项目定位在两条线之间的中心吗?
- c# - Unity - 使用旧坐标和它们之间的线长获取新坐标
- active-directory - 无 Office 计划且具有 PowerBI 许可证的未许可用户
- python - 进程变成僵尸 - Python3 多处理
- c# - 如何打印不是对象 IEnumerable 的值
()>() - html - 这个在 VueJS 中不起作用的 Click 事件有什么问题吗?
- powerquery - PowerQuery 表转换
- android - 如何在不部署到 GooglePlay 商店的情况下分发我的 Android 应用程序
- ruby - 使用 ruby 和 homebrew 移动手册页