【问题标题】:SwiftUI TextField LagSwiftUI 文本字段滞后
【发布时间】:2021-10-09 23:14:29
【问题描述】:

当我在给定视图中在 SwiftUI 中呈现多个文本字段时,我会得到明显的延迟,该延迟与文本字段的数量成正比。如果我将这些更改为简单的文本视图,则延迟会大大降低。

我查看了 SO 并发现了一些关于 TextField 滞后的问题,但一般来说滞后似乎主要是由数据源引起的,因为当使用常量值时,不会观察到滞后。

我创建了一个演示项目来说明这个问题。我有一个包含 20 个联系人姓名的数组,并为每个姓名创建一个包含三个电子邮件地址的联系人卡片。如果我在将电子邮件地址呈现为文本与文本字段视图(具有恒定值)之间切换视图,则从按钮点击到最后一个视图的 .onAppear 所需的时间为 80-100 毫秒(文本)和 300-320 毫秒(文本字段) .

两个视图都需要相当长的时间来呈现,但显然 TextField 在这个人为的、琐碎的应用程序上需要更长的时间来呈现。在我们的应用程序中,我们渲染了更多的信息,并且没有使用 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()
    }
}

【问题讨论】:

    标签: swift performance foreach swiftui lag


    【解决方案1】:

    在滚动视图中使用LazyVStack 而不是VStack。它对我有用,使用 200 个联系人姓名进行了测试。

    【讨论】:

    • 因此用 LazyVstack 替换内容视图主体中的 VStack 将文本视图的加载时间降低到 50-60 毫秒,将文本字段的加载时间降低到 230-240 毫秒。加载时间仍然大约长 3 倍。这一切都在运行 iOS 14.5 的模拟器中。 LazyVStack 的问题是我们试图保持与 iOS 13 的兼容性,而 LazyVStack 是 14+。我今天将在物理设备上进行测试,看看我还能找到什么。
    • 此外,通过在 UIViewRepresentable 中嵌入带有绑定字符串的 UITextView(没有标题,因为我们不使用该功能)创建自定义 TextField 将加载时间缩短了大约一半,因此 135-145 毫秒对于 OP 中描述的列表。我将在完整的应用程序中测试此解决方案,看看性能如何受到影响。
    • 我正在使用 macos 12.beta、xcode 13.beta、目标 ios 15 和 macCatalyst。在真机 ios 15 和 macos 12 上测试。我添加了几百个联系人没有任何问题。
    猜你喜欢
    • 1970-01-01
    • 2019-11-23
    • 2021-11-14
    • 2021-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    • 2020-12-20
    相关资源
    最近更新 更多