You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI如何让TextField/TextEditor在出现时自动成为第一响应者

问题原因

原有代码不生效的核心原因是onAppear回调触发时,TextEditor尚未完成向视图层级的挂载,此时对@FocusState绑定的变量赋值无法被视图正确响应,只有手动点击触发交互时才能正常激活聚焦状态。

解决方案

最简单的兼容方案是在聚焦状态赋值前增加极短的异步延迟,等待视图完成挂载后再触发聚焦,修改后的完整代码如下:

import SwiftUI

struct ContentView: View {
    
    @State var showTextField : Bool = false
    @State private var currentEditText : String = "Some text"
    @FocusState private var editTextFieldFocus: Bool
    
    var body: some View {
        VStack {
            Button {
                showTextField.toggle()
            } label: {
                Text("Show Text Field")
            }

            Text("Hello, world!")
                .padding()
            if showTextField{
                TextEditor(text: $currentEditText)
                    .focused($editTextFieldFocus)
                    .onAppear {
                        // 增加0.1秒延迟,等待视图挂载完成后再激活聚焦
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                            editTextFieldFocus = true
                        }
                    }
            }
            
        }
    }
}

补充说明:

  • 0.1秒的延迟是经验值,不会产生肉眼可见的卡顿,同时足够覆盖视图挂载的耗时
  • 如果需要适配macOS场景,可以在TextEditor的修饰符中额外添加.prefersDefaultFocus(in: .namespace)修饰符,配合命名空间使用优先聚焦逻辑
  • 也可以将赋值逻辑移到按钮的点击回调中,和showTextField的切换逻辑绑定,效果和onAppear中加延迟一致:
Button {
    showTextField.toggle()
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        editTextFieldFocus = showTextField
    }
} label: {
    Text("Show Text Field")
}

内容的提问来源于stack exchange,提问作者unknown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 23:54:04