点击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:
- 在
PopupViewController中新增闭包属性:
class PopupViewController: UIViewController { // 新增闭包,用于通知外部保存完成 var onSaveCompleted: (() -> Void)? // 原有代码... @objc func buttonAction(_ sender: UIButton) { // 保存主视图内容(你的原有逻辑) // 触发闭包,通知外部处理导航栏按钮修改 onSaveCompleted?() self.dismiss(animated: true) } }
- 在
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
相关产品推荐
相关产品推荐

