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

点击导航栏返回按钮后,如何从另一个ViewController隐藏/禁用按钮

嘿,我完全懂你现在卡在哪了——从训练项目选择页面返回后,想把计划页面里对应日期的按钮给禁用或者隐藏,但试了好多次都没成功对吧?别慌,我给你几个iOS开发里常用的解决方案,肯定能帮你搞定:

方法一:用闭包(Closure)传递状态

这是最轻便的方式,适合页面间简单的状态传递逻辑。核心思路是在第二个页面定义一个闭包,保存或返回时调用闭包把选中的日期传回去,第一个页面提前在闭包里写好更新按钮的逻辑。

第二个页面(训练项目选择VC)代码:

class TrainingSelectionVC: UIViewController {
    // 定义闭包,参数是选中的日期索引(比如1-7)
    var onSaveAndBack: ((Int) -> Void)?
    // 记录用户点击的是第几天的按钮
    var selectedDayIndex: Int?

    // 用户点击自定义保存按钮的方法
    @IBAction func saveButtonTapped(_ sender: UIButton) {
        // 先处理保存训练项目的逻辑
        // ...
        
        // 调用闭包传递日期索引
        if let index = selectedDayIndex {
            onSaveAndBack?(index)
        }
        // 手动返回上一页
        navigationController?.popViewController(animated: true)
    }

    // 处理用户直接点导航栏返回的情况
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // 判断是否是因为pop回上一页而消失
        if isMovingFromParent {
            if let index = selectedDayIndex {
                onSaveAndBack?(index)
            }
        }
    }
}

第一个页面(训练计划VC)代码:

class TrainingPlanVC: UIViewController {
    // 点击日期按钮跳转的方法
    @IBAction func dayButtonTapped(_ sender: UIButton) {
        let selectionVC = storyboard?.instantiateViewController(withIdentifier: "TrainingSelectionVC") as! TrainingSelectionVC
        // 用按钮的tag来标记日期索引(提前给7个按钮设置好tag:1-7)
        selectionVC.selectedDayIndex = sender.tag
        // 设置闭包,返回后更新按钮状态
        selectionVC.onSaveAndBack = { [weak self] dayIndex in
            guard let self = self else { return }
            // 找到对应tag的按钮,修改状态
            if let targetButton = self.view.viewWithTag(dayIndex) as? UIButton {
                targetButton.isEnabled = false // 禁用按钮
                // 或者 targetButton.isHidden = true // 隐藏按钮
            }
        }
        navigationController?.pushViewController(selectionVC, animated: true)
    }
}

注意一定要用[weak self]来避免循环引用哦!

方法二:代理模式(Delegate)

如果你的页面交互逻辑比较复杂,代理模式会让代码结构更清晰,耦合性更低。

第一步:定义代理协议

protocol TrainingSelectionDelegate: AnyObject {
    func didSaveTraining(forDay dayIndex: Int)
}

第二个页面(训练项目选择VC)代码:

class TrainingSelectionVC: UIViewController {
    weak var delegate: TrainingSelectionDelegate?
    var selectedDayIndex: Int?

    @IBAction func saveButtonTapped(_ sender: UIButton) {
        // 保存逻辑...
        if let index = selectedDayIndex {
            delegate?.didSaveTraining(forDay: index)
        }
        navigationController?.popViewController(animated: true)
    }

    // 处理导航栏返回的情况
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        if isMovingFromParent {
            if let index = selectedDayIndex {
                delegate?.didSaveTraining(forDay: index)
            }
        }
    }
}

第一个页面(训练计划VC)代码:

class TrainingPlanVC: UIViewController, TrainingSelectionDelegate {
    @IBAction func dayButtonTapped(_ sender: UIButton) {
        let selectionVC = storyboard?.instantiateViewController(withIdentifier: "TrainingSelectionVC") as! TrainingSelectionVC
        selectionVC.selectedDayIndex = sender.tag
        // 设置代理
        selectionVC.delegate = self
        navigationController?.pushViewController(selectionVC, animated: true)
    }

    // 实现代理方法,更新按钮状态
    func didSaveTraining(forDay dayIndex: Int) {
        if let targetButton = view.viewWithTag(dayIndex) as? UIButton {
            targetButton.isEnabled = false
        }
    }
}

方法三:通知中心(NotificationCenter)

如果两个页面的层级关系比较远,或者你不想直接关联两个VC,可以用通知中心,但要注意它的耦合性较高,尽量少用。

第二个页面(训练项目选择VC)代码:

@IBAction func saveButtonTapped(_ sender: UIButton) {
    // 保存逻辑...
    if let index = selectedDayIndex {
        // 发送通知,携带日期索引
        NotificationCenter.default.post(
            name: NSNotification.Name("DidSaveTraining"),
            object: nil,
            userInfo: ["dayIndex": index]
        )
    }
    navigationController?.popViewController(animated: true)
}

第一个页面(训练计划VC)代码:

class TrainingPlanVC: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 注册通知监听
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(updateDayButton(_:)),
            name: NSNotification.Name("DidSaveTraining"),
            object: nil
        )
    }

    @objc func updateDayButton(_ notification: Notification) {
        // 从通知里取出日期索引,更新按钮
        if let dayIndex = notification.userInfo?["dayIndex"] as? Int,
           let targetButton = view.viewWithTag(dayIndex) as? UIButton {
            targetButton.isEnabled = false
        }
    }

    // 记得销毁页面时移除观察者,避免内存泄漏
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

这三种方法都能解决你的问题,你可以根据自己项目的复杂度选最适合的~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:39:44