Jac*_*yla 5 ios swift swiftui lazyvstack
我有一个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 cell", text)
}
var body: some View {
Text(text)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,即使只更改 1 个单元格,每个单元格都会调用 init 。有什么办法可以避免这种情况吗?
这是一个工作代码,有一些要点需要提及,SwiftUI 中的 View 会在这里或那里或在 SwiftUI 认为需要的任何时候被初始化!但是如果主体中的某些值确实发生了变化,则视图的主体将会被计算。计划是这样工作的,但也有一些例外。就像主体被计算一样,即使主体中使用的值与以前一样没有变化,我不想介入该主题!但是在您的示例和问题中,我们希望 SwiftUI 仅呈现更改后的视图,为此目标,向下代码可以正常工作,没有问题,但正如您所看到的,我使用了 VStack,如果我们更改为 ,VStackSwiftUILazyVStack将呈现一些额外的视图它的秘密代码,如果你向下滚动然后向上滚动,它会忘记内存中的所有渲染视图和数据,并且它会尝试渲染旧的渲染视图,所以这是 的本质LazyVStack,我们对此无能为力。苹果想要LazyVStack变得懒惰。但您可以看到,这LazyVStack不会渲染所有视图,但其中一些视图需要工作。我们无法说出或知道有多少视图以惰性方式渲染,但肯定不是全部。
let initializingArray: () -> [String] = {
var items: [String] = [String]()
for _ in 0...200 { items.append(UUID().uuidString) }
return items
}
struct ContentView: View {
@State var items: [String] = initializingArray()
var body: some View {
ScrollView {
VStack {
ForEach(items, id: \.self) { item in
Button(action: {
if let index = self.items.firstIndex(where: { $0 == item }) {
items[index] = "changed \(index)"
}
}, label: {
ItemView(item: item)
})
}
}
}
}
}
struct ItemView: View {
let item: String
var body: some View {
print("Rendering row for:", item)
return Text(item)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1425 次 |
| 最近记录: |