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

