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

如何在ControllerOne收到通知时显示ControllerTwo中的按钮?

实现WebSocket通知触发ControllerTwo按钮显示的几种方案

这里有几种靠谱的方案帮你搞定这个需求,我结合你的现有代码给你详细拆解:

方案一:使用NotificationCenter(推荐,低耦合)

这是iOS里跨组件通信的常用方式,不需要两个控制器直接持有引用,耦合度很低,适合你这种场景。

步骤1:在NewDashboardViewController里注册通知监听

修改你的ControllerTwo.swift代码,在视图加载时注册一个自定义通知,收到通知后就显示按钮,同时记得在控制器销毁时移除观察者避免内存泄漏:

class NewDashboardViewController: UIViewController, UITableViewDataSource, UITabBarControllerDelegate, UITableViewDelegate {
    @IBOutlet weak var showNotificationsbtn: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 注册通知,监听"显示通知按钮"的事件
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(showNotificationButton),
            name: NSNotification.Name("ShowNotificationButtonEvent"),
            object: nil
        )
        // 初始状态隐藏按钮
        showNotificationsbtn.isHidden = true
    }
    
    // 收到通知后执行的方法,显示按钮
    @objc private func showNotificationButton() {
        showNotificationsbtn.isHidden = false
    }
    
    @IBAction func showNotifications(_ sender: Any) {
        showNotificationsbtn.isHidden = true
        // 注意:手动调用viewDidAppear(true)不太规范,这是系统的生命周期方法,建议换成你实际需要的操作
        // 比如如果要刷新表格,就写 tableView.reloadData()
    }
    
    // 控制器销毁时移除观察者,防止内存泄漏
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

步骤2:在ControllerOne的WebSocket回调里发送通知

修改ControllerOne.swift的websocket方法,当满足selectedIndex == 0的条件时,发送刚才定义的通知:

public func websocket(token: Any){
    self.ws.open("ws://"+String(APIHOST)+":"+String(port)+"/ws?token="+String(describing: token))
    self.ws.event.message = { message in
        let res = self.convertToDictionary(text: message as! String)
        guard let hasNotification = res?["notification"], hasNotification != nil else {
            return
        }
        
        self.count_total_notifications_ws = (self.count_total_notifications_ws ?? 0) + 1
        let presentView = UIApplication.shared.keyWindow?.rootViewController?.presentedViewController as? SWRevealViewController
        let tabbarController = presentView?.frontViewController as? UITabBarController
        
        if let tabbar = tabbarController {
            if tabbar.selectedIndex != 0 {
                tabbar.tabBarItems?[0].badgeValue = "\(self.count_total_notifications_ws ?? 0)"
            } else {
                // 发送通知,触发NewDashboardViewController显示按钮
                NotificationCenter.default.post(
                    name: NSNotification.Name("ShowNotificationButtonEvent"),
                    object: nil
                )
            }
        }
    }
}

方案二:直接获取NewDashboardViewController实例操作UI

这种方式更直接,但依赖你的页面层级结构,如果后续页面结构变化可能需要调整代码。

修改ControllerOne.swift里的else分支,直接找到当前显示的NewDashboardViewController实例,然后更新按钮状态(注意UI操作必须在主线程):

public func websocket(token: Any){
    self.ws.open("ws://"+String(APIHOST)+":"+String(port)+"/ws?token="+String(describing: token))
    self.ws.event.message = { message in
        let res = self.convertToDictionary(text: message as! String)
        guard let hasNotification = res?["notification"], hasNotification != nil else {
            return
        }
        
        self.count_total_notifications_ws = (self.count_total_notifications_ws ?? 0) + 1
        let presentView = UIApplication.shared.keyWindow?.rootViewController?.presentedViewController as? SWRevealViewController
        let tabbarController = presentView?.frontViewController as? UITabBarController
        
        if let tabbar = tabbarController {
            if tabbar.selectedIndex != 0 {
                tabbar.tabBarItems?[0].badgeValue = "\(self.count_total_notifications_ws ?? 0)"
            } else {
                // 根据你的页面层级获取NewDashboardViewController实例
                if let navVC = tabbar.selectedViewController as? UINavigationController {
                    // 如果是嵌套在导航控制器里
                    if let dashboardVC = navVC.rootViewController as? NewDashboardViewController {
                        DispatchQueue.main.async {
                            dashboardVC.showNotificationsbtn.isHidden = false
                        }
                    }
                } else {
                    // 如果直接是tabbar的子控制器
                    if let dashboardVC = tabbar.selectedViewController as? NewDashboardViewController {
                        DispatchQueue.main.async {
                            dashboardVC.showNotificationsbtn.isHidden = false
                        }
                    }
                }
            }
        }
    }
}

注意事项

  • 所有UI操作必须在主线程执行,WebSocket的回调一般在子线程,所以一定要用DispatchQueue.main.async包裹UI修改代码,避免崩溃。
  • 方案一的通知名称建议用唯一的字符串,比如加上你的项目前缀,防止和其他第三方库的通知冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:02:21