SwiftUI 中的列表真的很懒吗?我有一个从 coreData 获取的 5000 个元素的列表,我想将它们显示在列表中。我读了很多评论(例如: https: //developer.apple.com/forums/thread/651256),认为列表是懒惰的,但对我来说,看起来它们不是......加载列表需要 15 秒。
List(element, id: \.objectID, selection: $selection) { file in
RowView(file)
}
Run Code Online (Sandbox Code Playgroud)
如果我使用 ScrollView + LazyVStack + ForEach 代替,加载时间不到一秒。
ScrollView {
LazyVStack(alignment: .leading, spacing: 0) {
ForEach(element, id: \.objectID) { file in
RowView(file)
.onTapGesture {
selection = Set([file.objectID])
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我更喜欢列出一个列表来利用它提供的功能。我做错了什么还是列表不懒惰?
感谢帮助!(我正在使用 SwiftUI(适用于 Mac))。
当我使用列表视图时,我可以轻松添加修饰符refreshable来触发刷新逻辑。我的问题是如何在使用 LazyVStack 时实现相同的目标。
我有以下代码:
struct TestListView: View {
var body: some View {
Text("the list view")
// WORKS:
// VStack {
// List {
// ForEach(0..<10) { n in
// Text("N = \(n)")
// }
// }
// .refreshable {
//
// }
// }
// DOES NOT SHOW REFRESH CONTROL:
ScrollView {
LazyVStack {
ForEach(0..<10) { n in
Text("N = \(n)")
}
}
}
.refreshable {
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下如何获得刷新行为LazyVStack?
在使用and /时,我遇到了许多类似的问题,其中惰性堆栈的内容在.ScrollViewLazyVStackLazyHStackScrollView
首先,我认为这可能是由于在惰性堆栈上使用复杂的视图,这会导致 SwiftUI 中的布局问题,但我设法想出了一个使用非常简单的视图层次结构的 MWE,但问题仍然存在。
当快速向左滚动以及在 的前缘弹跳时,这会导致卡顿ScrollView:
ScrollView(.horizontal) {
LazyHStack {
Color.red.frame(width: 450)
Color.green.frame(width: 250)
Color.blue.frame(width: 250)
}
}
.frame(width: 350)
Run Code Online (Sandbox Code Playgroud)
减小第一个视图的宽度可以消除卡顿现象
ScrollView(.horizontal) {
LazyHStack {
Color.red.frame(width: 400) //<- No stutter
Color.green.frame(width: 250)
Color.blue.frame(width: 250)
}
}
.frame(width: 350)
Run Code Online (Sandbox Code Playgroud)
对于这个 MWE,口吃似乎只发生在设备上(可能是因为我在模拟器中滚动得不够快)。然而,我在具有更复杂视图的模拟器中也遇到了同样的问题。
如果这是 SwiftUI 中的错误,您有什么想法吗?
在装有 Xcode 13 beta 1 和 iOS 15 的 iPhone Xs Max 上进行了测试。
我有一个LazyVStack我只想更新一个视图而不是重新加载屏幕上的所有其他视图的视图。对于更复杂的单元,这会导致性能大幅下降。我已经包含了示例代码
import SwiftUI
struct ContentView: View {
@State var items = [String]()
var body: some View {
ScrollView {
LazyVStack {
ForEach(self.items, id: \.self) { item in
Button {
if let index = self.items.firstIndex(where: {$0 == item}) {
self.items[index] = "changed \(index)"
}
} label: {
cell(text: item)
}
}
}
}
.onAppear {
for _ in 0...200 {
self.items.append(NSUUID().uuidString)
}
}
}
}
struct cell: View {
let text: String
init(text: String) {
self.text = text
print("init …Run Code Online (Sandbox Code Playgroud) TL;DR:是否有一些参数或方法可以设置 LazyVStack 初始化视图的偏移量?
LazyVStack 延迟初始化视图,因此当我滚动时,下一个(几个?)视图将被初始化。我在绘制视图后加载图像,使用 swift 中的 SDWebImage 包。这需要几毫秒的时间来查看视图,并且由于我使用的是 LazyVStack,如果滚动速度很快(即使在合理的限制内),占位符会在短时间内可见,因为视图刚刚(太)短的一刻之前创建。如果我滚动速度非常慢,图像将在视图出现之前加载,因此看不到占位符。
如果我能让 LazyVStack 提前几毫秒初始化视图,我的问题就会消失......
曾经认为这是一个非常常见的问题,正确安排初始化时间以免加载太早或太晚..但文档中对此没有任何内容