【问题标题】:SwiftUI - How to modify textfield in an arraySwiftUI - 如何修改数组中的文本字段
【发布时间】:2021-09-06 14:09:45
【问题描述】:

在以下代码中,您可以将其复制到一个新的 SwiftUI 项目中,当我运行它并开始在文本字段中输入时,该字段在每个字符后失去焦点。我怎样才能解决这个问题?我不了解可观察对象,所以也许这就是问题所在?顺便说一句,我使用的是 Xcode 13.0 Beta 5

struct CmdOption: Hashable, Identifiable {
    var id: UUID { UUID() }
    var value: String
}

import SwiftUI

struct ContentView: View {
    
    @State var theOptions: [CmdOption] = [
        CmdOption(value: ""),
        CmdOption(value: "")
    ]
    
    @State var allOptions: [CmdOption] = []
    
    var body: some View {
        VStack {
            ScrollView(.vertical) {
                ForEach($allOptions, id: \.self)  { $option in
                    VStack {
                        TextField(option.value, text: $option.value)
                    }
                }
            }
        }.onAppear {
            startup()
        }
    }
    func startup() {
        allOptions.removeAll()
        theOptions.forEach {option in
            allOptions.append(option)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

【问题讨论】:

    标签: arrays swiftui


    【解决方案1】:

    有两个问题:

    1. 您将id 作为计算属性。这意味着 每次 您尝试读取该值时它都会发生变化。
    2. 您正在使用id: \.self,它不是唯一的(因为id 也被存储为计算属性,所以默认Hashable 一致性不考虑它)。

    要解决此问题,请将 CmdOption 更改为以下内容:

    struct CmdOption: Hashable, Identifiable {
        let id: UUID = UUID()
        var value: String
    }
    

    还有你的ForEach(隐含id: \.id):

    ForEach($allOptions) { $option in
        VStack {
            TextField(option.value, text: $option.value)
        }
    }
    

    现在,这些视图的 ID 是常量唯一TextFields 现在将不再失去焦点,因为它们不会在每次重新计算 ContentView 的主体时重新创建视图,因为它们的 ID 保持不变。请参阅 Demystify SwiftUI - WWDC21 了解有关 ID 如何影响视图生命周期的更多信息。

    【讨论】:

    • 谢谢乔治。这解决了它。
    猜你喜欢
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    • 1970-01-01
    相关资源
    最近更新 更多