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

Zendesk iOS:Messaging实例嵌入导航控制器后UIBarButtonItem不显示

解决Zendesk Messaging UI嵌入UINavigationController后导航栏按钮不显示的问题

我之前也碰到过一模一样的问题!Zendesk的Messaging视图控制器内部会自己创建并管理导航栏组件,直接给它的navigationItem设置按钮大概率会被覆盖或者根本不生效,这里给你几个经过验证的可行方案:

方案1:给导航控制器的顶层视图控制器绑定按钮

既然我们是用UINavigationController包裹Zendesk的VC,不如直接操作导航控制器的topViewController,避开Zendesk内部的导航栏干扰:

if let zendeskSupportVC = ZendeskController().createInstance() {
    let navigationController = UINavigationController(rootViewController: zendeskSupportVC)
    // 直接给导航控制器的顶层VC设置标题和按钮
    navigationController.topViewController?.title = NSLocalizedString("Contact Us", comment: "Contact Us")
    let dismissBtn = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissSupportPage))
    navigationController.topViewController?.navigationItem.rightBarButtonItem = dismissBtn
    self.present(navigationController, animated: true)
}

不过这个方法偶尔会因为Zendesk内部的视图生命周期触发而失效,要是碰到这种情况,可以试试方案2。

方案2:利用Zendesk官方的UI配置接口

Zendesk的Messaging SDK其实提供了自定义导航栏的配置项,我们可以在构建UI的时候就把按钮配置进去,从根源上避免被覆盖:

先修改你的createInstance方法,给MessagingConfiguration添加导航栏配置:

func createInstance() -> UIViewController? {
    do {
        let requestConfiguration = RequestUiConfiguration()
        var messagingConfiguration = MessagingConfiguration()
        
        // 配置导航栏标题和右侧按钮
        let navConfig = NavigationBarConfiguration(
            title: NSLocalizedString("Contact Us", comment: "Contact Us"),
            rightBarButtonItems: [UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: nil)]
        )
        messagingConfiguration.navigationBarConfiguration = navConfig
        
        let answerBotEngine = try AnswerBotEngine.engine()
        let supportEngine = try SupportEngine.engine()
        let chatEngine = try ChatEngine.engine()
        
        let zendeskVC = try Messaging.instance.buildUI(
            engines: [answerBotEngine, supportEngine, chatEngine],
            configs: [messagingConfiguration, requestConfiguration]
        )
        return zendeskVC
    } catch let error {
        print("Error launching Zendesk: \(error)")
        return nil
    }
}

这里要注意:配置里的按钮没法直接绑定target和action,我们可以在呈现后延迟一点,找到按钮再绑定:

@objc func dismissSupportPage() {
    self.dismiss(animated: true)
}

// 呈现时绑定按钮事件
if let zendeskSupportVC = ZendeskController().createInstance() {
    let navigationController = UINavigationController(rootViewController: zendeskSupportVC)
    self.present(navigationController, animated: true) {
        // 延迟确保视图加载完成
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            if let doneBtn = navigationController.topViewController?.navigationItem.rightBarButtonItems?.first {
                doneBtn.target = self
                doneBtn.action = #selector(self.dismissSupportPage)
            }
        }
    }
}

方案3:自定义导航控制器子类(最稳定)

如果前两个方案都不稳,那可以创建一个自定义导航控制器子类,在viewDidAppear里强制设置导航栏按钮,确保不会被Zendesk的内部逻辑打断:

class ZendeskNavigationController: UINavigationController {
    weak var dismissDelegate: UIViewController?
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // 强制覆盖导航栏配置
        self.topViewController?.title = NSLocalizedString("Contact Us", comment: "Contact Us")
        let dismissBtn = UIBarButtonItem(barButtonSystemItem: .done, target: dismissDelegate, action: #selector(dismissDelegate?.dismissSupportPage))
        self.topViewController?.navigationItem.rightBarButtonItem = dismissBtn
    }
}

然后用这个子类来呈现Zendesk的VC:

if let zendeskSupportVC = ZendeskController().createInstance() {
    let navController = ZendeskNavigationController(rootViewController: zendeskSupportVC)
    navController.dismissDelegate = self
    self.present(navController, animated: true)
}

我当时踩坑后用的是方案3,稳定性拉满,完全不会被Zendesk的内部更新干扰,你可以根据自己的场景选合适的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:42:47