SwiftUI键盘聚焦时UINavigationBar返回按钮无响应问题求助
解决方案
方案1:限制SwiftUI视图不延伸到导航栏区域
问题大概率是SwiftUI视图默认延伸到导航栏下方,键盘弹出时该区域的视图拦截了导航栏按钮的点击事件。你可以在创建UIHostingController时设置edgesForExtendedLayout,让视图仅延伸至底部:
let controller = UIHostingController(rootView: view) controller.edgesForExtendedLayout = .bottom // 仅允许视图延伸至底部安全区外 controller.modalPresentationStyle = .fullScreen
同时在SwiftUI视图的顶层容器中,确保内容在安全区内显示:
public var body: some View { VStack { // ... 现有内容 } .safeAreaInset(edge: .top) { Color.clear } // 确保顶部内容不超出安全区 // ... 其他修饰符 }
方案2:强制导航栏在键盘弹出时处于视图层级最顶层
如果方案1无效,可通过监听键盘通知,确保导航栏在键盘弹出时被带到视图最前面,优先接收点击事件:
修改createMFALoginNavigationViewController方法,添加键盘监听逻辑:
func createMFALoginNavigationViewController<V: View>(with hostingController: UIHostingController<V>) -> UINavigationController { let backImage = ConsumerUI.Asset.Icons.chevronLeft.image.withRenderingMode(.alwaysOriginal) let navigationController = UINavigationController(rootViewController: hostingController) navigationController.navigationBar.configureConsumerDefaultStyle() navigationController.modalPresentationStyle = .fullScreen navigationController.presentationController?.delegate = self hostingController.navigationItem.leftBarButtonItem = UIBarButtonItem(image: backImage, style: .plain, closure: { [weak hostingController] _ in hostingController?.dismiss(animated: ConsumerUIModule.areAnimationsEnabled) }) // 监听键盘弹出,将导航栏置于顶层 NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { [weak navigationController] _ in guard let navBar = navigationController?.navigationBar else { return } navBar.superview?.bringSubviewToFront(navBar) } return navigationController }
方案3:调整SwiftUI视图的事件穿透规则
如果前两个方案都不生效,可以让SwiftUI视图的顶层容器忽略导航栏区域的点击事件,确保事件能透传到下层的UIKit导航栏:
在SwiftUI视图的顶层VStack添加以下修饰符:
public var body: some View { VStack { // ... 现有内容 } .contentShape(Rectangle()) .allowsHitTesting(false) .overlay( // 仅让非导航栏区域接收点击事件 Rectangle() .frame(maxHeight: .infinity, alignment: .bottom) .allowsHitTesting(true) ) // ... 其他修饰符 }
补充排查点
- 暂时注释
resendSMSView的.zIndex(2)修饰符,排查是否是该视图意外延伸到导航栏区域导致的事件拦截。 - 检查
configureConsumerDefaultStyle方法中,是否误将UINavigationBar的isUserInteractionEnabled设置为false。
内容的提问来源于stack exchange,提问作者Sevenfortyseven
相关产品推荐
相关产品推荐

