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

使用.fullScreenCover展示视图时键盘工具栏不显示的问题

fullScreenCover弹出视图中onAppear设置TextField焦点时键盘工具栏不显示的解决办法

问题现象

用.fullScreenCover弹出的SecondView中,在.onAppear方法里通过@FocusState为第一个TextField设置焦点时,弹出的键盘不会显示自定义工具栏;但通过按钮手动触发焦点设置,或者改用.sheet弹出视图时,键盘工具栏能正常显示。已尝试将视图嵌入NavigationStack、VStack等组件,均无法解决问题。

原因分析

这是由于fullScreenCover的视图在.onAppear触发时,视图层级和布局还未完全稳定,此时直接设置焦点会导致键盘工具栏的布局逻辑未被正确触发。

解决办法

有两种可行的修复方式:

方式一:用DispatchQueue.main.async延迟设置焦点

将焦点设置代码放入主队列异步任务,让视图完全渲染完成后再执行:

.onAppear(perform: {
    DispatchQueue.main.async {
        focusedTextfield = .firstTextField
    }
})

方式二:用.task修饰符替代.onAppear(iOS 15+)

.task会在视图生命周期的合适时机执行代码,确保布局稳定后再触发焦点设置:

.task {
    focusedTextfield = .firstTextField
}

修改后的完整代码示例

以.task方式为例,修改后的SecondView代码如下:

struct SecondView: View {
    
    @State var first: String = ""
    @State var second: String = ""
    
    @FocusState private var focusedTextfield: TextFields?

    var body: some View {
        NavigationStack {
            Button("Show Keyboard") {
                focusedTextfield = .firstTextField
            }
            
            VStack(spacing: 20) {
                TextField(text: $first) {
                    Text("first")
                }
                .focused($focusedTextfield, equals: .firstTextField)
                
                TextField(text: $second) {
                    Text("second")
                }
                .focused($focusedTextfield, equals: .secondTextField)
            }
            
            Spacer()
                .toolbar {
                    ToolbarItemGroup(placement: .keyboard) {
                        Button(action: {}, label: { Text("Prev") })
                        Button(action: {}, label: { Text("Next") })
                        Spacer()
                        Button(action: {}, label: {
                            Image(systemName: "keyboard.chevron.compact.down")
                        })
                    }
                }
                .navigationTitle("Second View")
                .task {
                    focusedTextfield = .firstTextField
                }
        }
    }
    
    enum TextFields {
        case firstTextField
        case secondTextField
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 23:07:55