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

如何在另一个UIView中触发ViewController的dismiss操作

实现方案

下面提供3种常用的实现方式,可根据你的项目场景选择:

方案1:通过响应者链直接查找ViewController(无额外耦合,快速实现)

利用iOS响应者链机制,沿视图层级向上查找当前所属的ViewController,直接调用dismiss即可:

@objc func cancelButtonTapped() {
    var nextResponder = self.next
    while let responder = nextResponder {
        if let vc = responder as? UIViewController {
            vc.dismiss(animated: true)
            break
        }
        nextResponder = responder.next
    }
}

方案2:闭包回调(耦合低、灵活度高,推荐常用场景)

在自定义View中暴露回调闭包,由持有该View的ViewController实现dismiss逻辑:

  1. 首先在你的自定义UIView类中定义回调属性:
// 自定义UIView类内部
var cancelButtonTappedCallback: (() -> Void)?
  1. 补全按钮点击方法,触发回调:
@objc func cancelButtonTapped() {
    cancelButtonTappedCallback?()
}
  1. 在初始化该自定义View的ViewController中,实现闭包逻辑:
// ViewController 中初始化自定义View的位置
let customView = YourCustomView()
customView.cancelButtonTappedCallback = { [weak self] in
    self?.dismiss(animated: true)
    // 如果是push出来的页面,替换为下面的代码
    // self?.navigationController?.popViewController(animated: true)
}

方案3:代理模式

和闭包逻辑类似,通过代理协议传递点击事件:

  1. 定义代理协议:
protocol CustomViewActionDelegate: AnyObject {
    func didTriggerCancelAction()
}
  1. 自定义View中添加代理属性,点击时调用代理方法:
// 自定义UIView类内部
weak var delegate: CustomViewActionDelegate?

@objc func cancelButtonTapped() {
    delegate?.didTriggerCancelAction()
}
  1. ViewController遵守协议,实现代理方法:
extension YourViewController: CustomViewActionDelegate {
    func didTriggerCancelAction() {
        dismiss(animated: true)
    }
}

// 初始化View时设置代理
let customView = YourCustomView()
customView.delegate = self

注意事项:如果当前ViewController是UINavigationController push进来的,需要把dismiss(animated: true)替换为navigationController?.popViewController(animated: true);使用闭包/代理时要加[weak self]避免循环引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 01:54:03