当我在一个给定的视图中用SwiftUI呈现多个文本字段时,我得到了明显的滞后,这与文本字段的数量成正比。如果我将这些更改为简单的文本视图,延迟就会大大降低。
我已经查看了TextField,并发现了一些关于滞后的问题,但一般来说,滞后似乎是由数据源引起的,因为当使用常量值时,滞后不会被观察到。
我已经创建了一个演示项目来说明这个问题。我有一个由20个联系人姓名组成的数组,并为每个姓名创建一个带有三个电子邮件地址的联系人卡片。如果我在以文本形式呈现电子邮件地址和以常量值呈现TextField视图之间切换视图,则从点击按钮到最后一个视图的.onAppear所需的时间分别为80-100毫秒(文本)和300-320毫秒(TextField)。
这两个视图都需要明显的渲染时间,但很明显,在这个精心设计的、琐碎的应用程序上,TextFields渲染的时间要长得多。在我们的应用程序中,我们渲染了更多的信息,并且不使用常量值作为TextFields,因此这种延迟会产生更明显的效果(有时只有几秒钟)。对于SwiftUI TextFields,有什么解决这个问题的方法吗?以下是演示项目的代码。我知道有更好的方法来编写代码,只是快速地将它们组合在一起来演示速度问题。
此外,有趣的是,如果我将ForEach放入列表中(或仅尝试直接使用来自数组数据的列表),则根本不会呈现ContactCard视图。
任何帮助都是非常感谢的!
import SwiftUI
var formatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
return formatter
}
struct ContentView: View {
let contacts: Array<(first: String, last: String)> = [
("John", "Stone"),
("Ponnappa", "Priya"),
("Mia", "Wong"),
("Peter", "Stanbridge"),
("Natalie", "Lee-Walsh"),
("Ang", "Li"),
("Nguta", "Ithya"),
("Tamzyn", "French"),
("Salome", "Simoes"),
("Trevor", "Virtue"),
("Tarryn", "Campbell-Gillies"),
("Eugenia", "Anders"),
("Andrew", "Kazantzis"),
("Verona", "Blair"),
("Jane", "Meldrum"),
(" Maureen", "M. Smith"),
("Desiree", "Burch"),
("Daly", "Harry"),
("Hayman", "Andrews"),
("Ruveni", "Ellawala")
]
@State var isTextField = false
var body: some View {
ScrollView {
VStack {
HStack {
Button("Text") {
print("text tapped: \(formatter.string(from: Date()))")
isTextField = false
}
Button("TextField") {
print("text tapped: \(formatter.string(from: Date()))")
isTextField = true
}
}
ForEach(contacts, id: \.self.last) { contact in
ContactCard(name: contact, isTextField: $isTextField)
}
}
}
}
}
struct ContactCard: View {
var name: (first: String, last: String)
@Binding var isTextField: Bool
var emailAddresses: Array<String> {
[
"\(name.first).\(name.last)@home.com",
"\(name.first).\(name.last)@work.com",
"\(name.first).\(name.last)@work.org",
]
}
var body: some View {
VStack {
Text("\(name.first) \(name.last)")
.font(.headline)
ForEach(emailAddresses, id: \.self) { email in
HStack {
Text("Email")
.frame(width: 100)
if isTextField {
TextField("", text: .constant(email))
.onAppear(){
print("view appeared: \(formatter.string(from: Date()))")
}
} else {
Text(email)
.onAppear(){
print("view appeared: \(formatter.string(from: Date()))")
}
}
Spacer()
}
.font(.body)
}
}
.padding()
}
}发布于 2021-08-05 00:36:22
在滚动视图中使用LazyVStack而不是VStack。它对我很有效,使用了200个联系人姓名进行了测试。
https://stackoverflow.com/questions/68658208
复制相似问题