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

点击PopupViewController按钮后,如何修改MainViewController导航栏按钮标题并禁用?

问题

我在MainViewController中通过以下代码创建了一个导航栏按钮:

override func viewDidLoad() {
    super.viewDidLoad()    

    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Save", style: .plain, target: self, action: #selector(presentPopup))
        
}
    
@objc func presentPopup() {
        
    let popupVC = PopupViewController()
    popupVC.modalPresentationStyle = .overCurrentContext
    present(popupVC, animated: true, completion: nil)
        
}

该按钮会弹出一个包含“保存”按钮的弹窗表单,用于保存主视图的内容。我希望PopupViewController中的这个“保存”按钮能够实现两个功能:(1) 将MainViewController的导航栏按钮标题修改为“Saved”;(2) 禁用该导航栏按钮。

目前PopupViewController中的代码如下:

let popupBox: UIView = {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()

let button: UIButton = {
    let view = UIButton()
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()

override func viewDidLoad() {
    super.viewDidLoad()
        
    self.definesPresentationContext = true
    view.backgroundColor = .clear
        
    view.addSubview(popupBox)
    // configure popupBox

    view.addSubview(button)
    // configure button
    button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        
}

@objc func buttonAction(_ sender: UIButton) {
    // save main VC's contents
    // change title of main VC's nav button - WHAT GOES HERE?
    // disable main VC's nav button - WHAT GOES HERE?
    self.dismiss(animated: true)  // dismiss popup
    
}

请问我需要在按钮的buttonAction方法中添加什么代码来实现上述需求?

解决方案

方法一:直接通过presentingViewController强转(快速实现)

在PopupViewController的buttonAction方法中,将当前的presentingViewController强制转换为MainViewController,直接修改导航栏按钮的属性:

@objc func buttonAction(_ sender: UIButton) {
    // 保存主视图内容(你的原有逻辑)
    
    // 修改主VC导航按钮的标题并禁用
    if let mainVC = presentingViewController as? MainViewController {
        mainVC.navigationItem.rightBarButtonItem?.title = "Saved"
        mainVC.navigationItem.rightBarButtonItem?.isEnabled = false
    }
    
    self.dismiss(animated: true)
}

这种方式简单直接,但PopupViewController会和MainViewController产生强耦合,后续弹窗若要复用在其他控制器中,代码需调整。

方法二:使用闭包回调(解耦推荐)

这种方式遵循iOS开发解耦原则,让PopupViewController不直接依赖MainViewController:

  1. 在PopupViewController中新增闭包属性:
class PopupViewController: UIViewController {
    // 新增闭包,用于通知外部保存完成
    var onSaveCompleted: (() -> Void)?
    
    // 原有代码...
    
    @objc func buttonAction(_ sender: UIButton) {
        // 保存主视图内容(你的原有逻辑)
        
        // 触发闭包,通知外部处理导航栏按钮修改
        onSaveCompleted?()
        
        self.dismiss(animated: true)
    }
}
  1. 在MainViewController的presentPopup方法中,给弹窗的闭包赋值:
@objc func presentPopup() {
    let popupVC = PopupViewController()
    popupVC.modalPresentationStyle = .overCurrentContext
    
    // 赋值闭包,在此处理导航栏按钮修改逻辑
    popupVC.onSaveCompleted = { [weak self] in
        guard let self = self else { return }
        self.navigationItem.rightBarButtonItem?.title = "Saved"
        self.navigationItem.rightBarButtonItem?.isEnabled = false
    }
    
    present(popupVC, animated: true, completion: nil)
}

这种方式下PopupViewController可独立复用,所有和主控制器相关的逻辑都留在MainViewController中,代码耦合度更低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:53:23