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
相关产品推荐
相关产品推荐

