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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 01:07:05