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

如何在单个UIViewController中通过按钮点击调用并显示多个自定义Alert视图?

如何在单个ViewController上同时显示两个自定义Alert

首先看你当前代码里的几个关键问题,这些问题会导致你无法同时显示两个Alert,甚至第一个Alert都可能显示异常:

  1. 过时的keyWindow用法:iOS13+之后UIApplication.shared.keyWindow已经被废弃,而且直接把Alert加到keyWindow上,不如加到当前ViewController的view层级里更可控。
  2. 单例的错误使用:自定义Alert用单例的话,每次调用ShowAlert都会重复添加同一个parentView到视图层级,导致重复显示或者状态混乱,应该每次创建新的实例。
  3. 布局初始化错误:CommonInit方法里的frame设置有问题,比如FirstCustomAlert里的alertView(应该是parentView?)frame起点用了center.x和center.y,这会让你的Alert视图偏移到屏幕外;而且SecondCustomAlert的CommonInit根本没被调用,导致布局没生效。
  4. 多余的dismiss调用:ViewControllerA里的self.dismiss(animated: true, completion: nil)会把当前VC关掉,反而看不到Alert,应该删掉。

下面是修复后的完整代码,我会标注关键修改点:

修复后的ViewControllerA

class ViewControllerA : UIViewController{
    @IBAction func ViewControllerAButtonTapped(_ sender: Any) {
        // 创建FirstCustomAlert的新实例,而非单例
        let firstAlert = FirstCustomAlert()
        // 把Alert加到当前VC的view上,替代keyWindow
        firstAlert.showAlert(on: self.view)
        // 移除多余的dismiss调用
    }
}

修复后的FirstCustomAlert

class FirstCustomAlert : UIView{
    @IBOutlet var parentView: UIView!
    @IBOutlet weak var firstTextField: UITextField!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        Bundle.main.loadNibNamed("FirstCustomAlert", owner: self, options: nil)
        commonInit() // 调用初始化方法
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func commonInit(){
        // 正确设置parentView的frame,铺满整个自定义View
        parentView.frame = bounds
        parentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        // 将parentView添加到当前自定义View上
        addSubview(parentView)
    }
    
    // 修改方法参数,接收要添加到的父视图
    func showAlert(on parentView: UIView){
        // 设置当前自定义View的frame为父视图的bounds
        self.frame = parentView.bounds
        self.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        parentView.addSubview(self)
    }
    
    @IBAction func SubmitBittonTapped(_ sender: Any) {
        // 创建SecondCustomAlert的新实例
        let secondAlert = SecondCustomAlert()
        // 把第二个Alert加到同一个父视图(ViewControllerA的view)上
        secondAlert.showAlert(on: self.superview!)
    }
}

修复后的SecondCustomAlert

class SecondCustomAlert : UIView{
    @IBOutlet var parentView: UIView!
    @IBOutlet weak var secondTextField: UITextField!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        Bundle.main.loadNibNamed("SecondCustomAlert", owner: self, options: nil)
        commonInit() // 现在调用初始化方法了
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func commonInit(){
        parentView.frame = bounds
        parentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(parentView)
    }
    
    func showAlert(on parentView: UIView){
        self.frame = parentView.bounds
        self.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        parentView.addSubview(self)
    }
}

关键修改说明

  • 移除单例模式:每次需要显示Alert时创建新实例,避免重复添加同一视图和状态混乱。
  • 调整视图层级:将自定义Alert加到当前ViewController的view上,层级更清晰,符合iOS视图管理规范。
  • 修复布局初始化:确保commonInit被调用,正确设置parentView的frame和autoresizingMask,让Alert能适配父视图(你也可以根据需求改成居中弹窗样式)。
  • 删除无效dismiss:ViewControllerA里的dismiss会关闭自身,导致无法看到Alert,因此移除该代码。

修改后,点击ViewControllerA的按钮会显示第一个Alert;点击第一个Alert的提交按钮,第二个Alert会叠加显示在第一个上面,两个Alert都处于ViewControllerA的视图层级中,就能实现你想要的同时显示效果了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:15:18