SwiftUI中List内TextField在列表为空时失去焦点问题
SwiftUI列表为空时提交后TextField无法恢复焦点的解决方法
问题本质
当列表处于空状态时,添加第一个产品后,List会重新渲染内部视图结构,此时在onSubmit中同步设置isFieldFocused = true时机过早,TextField尚未完成视图重建,导致焦点设置失效;而列表已有元素时,视图结构无需大幅变更,同步设置即可生效。
解决方案
使用DispatchQueue.main.async延迟执行焦点设置,确保列表视图更新完成后再恢复TextField的焦点。同时优化输入判断逻辑,避免空字符串或纯空格提交。
修改后的完整代码
struct ContentView: View { @State var products: [String] = [] @State var newProductName = "" @FocusState private var isFieldFocused: Bool var body: some View { List { ForEach(products, id: \.self) { product in Text(product) } TextField("输入产品名", text: $newProductName) .focused($isFieldFocused) .onSubmit { // 过滤空字符串和纯空格 let trimmedName = newProductName.trimmingCharacters(in: .whitespaces) guard !trimmedName.isEmpty else { return } products.append(trimmedName) newProductName = "" // 延迟设置焦点,等待视图更新完成 DispatchQueue.main.async { isFieldFocused = true } } } // 可选:页面加载时自动聚焦输入框 .onAppear { isFieldFocused = true } } }
补充说明
DispatchQueue.main.async将焦点操作放到主队列的下一次循环,确保List完成视图重建后,TextField已经处于可用状态,此时设置焦点才能生效。- 用
trimmingCharacters处理输入内容,比原代码的判断逻辑更严谨,能避免用户输入纯空格的无效内容。 - 添加
onAppear自动聚焦,提升用户首次使用的体验。
内容的提问来源于stack exchange,提问作者Zef
相关产品推荐
相关产品推荐

