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

如何将UIView从UIViewController移至Window并置顶于所有控制器视图?

问题:将UIView从ViewController移至应用Window并置于所有视图上层

你现在遇到的核心问题是:你只是在原父视图(ViewController的view)内调整了子视图的层级,并没有真正把这个UIView转移到Window上,所以它还是被限制在当前ViewController的视图范围内,无法覆盖其他ViewController的内容。另外还要注意,iOS 13及以后UIApplication.shared.keyWindow已经被弃用,需要用新的方式获取当前活跃的Window。

原代码的问题点

  • window.bringSubview(toFront: view) 这个方法仅能让view在它当前的父视图里移到最前面,但你的view此时还是self.view的子视图,根本没和Window产生关联,所以这个调用完全不会改变它的父容器。
  • 变量名view和ViewController自带的view重名了,这会导致代码歧义,很容易引发隐藏问题,建议改成customView这类专属命名。

正确实现方案

要实现你的需求,需要完成这几个关键步骤:

  1. 先把目标View从原来的父视图中移除
  2. 获取当前应用的活跃Window(适配iOS13+)
  3. 将目标View添加到Window上,并设置正确的布局(frame或Auto Layout约束)
  4. 确保它处于Window的最上层(可选,新添加的子视图默认就在上层,保险起见可以加上)

修改后的完整代码如下:

class ViewController: UIViewController { 
    // 重命名变量,避免和系统view冲突
    var customView = UIView() 
    
    override func viewDidLoad() { 
        super.viewDidLoad() 
        // 给customView设置样式,方便观察效果
        customView.backgroundColor = .red
        customView.frame = CGRect(x: 50, y: 50, width: 200, height: 200)
        self.view.addSubview(customView)
        
        // 添加测试按钮,绑定点击事件
        let button = UIButton(type: .system)
        button.setTitle("移到Window", for: .normal)
        button.frame = CGRect(x: 50, y: 300, width: 200, height: 50)
        button.addTarget(self, action: #selector(tappedAction), for: .touchUpInside)
        self.view.addSubview(button)
    } 
    
    @objc func tappedAction() { 
        // 1. 从原父视图移除
        customView.removeFromSuperview()
        
        // 2. 获取当前活跃的Window(适配iOS13+多场景)
        guard let window = UIApplication.shared.connectedScenes
                .filter({$0.activationState == .foregroundActive})
                .map({$0 as? UIWindowScene})
                .compactMap({$0})
                .first?.windows
                .filter({$0.isKeyWindow}).first else {
            return
        }
        
        // 3. 添加到Window并设置布局(这里用frame示例,也可以用Auto Layout)
        customView.frame = window.bounds.inset(by: UIEdgeInsets(top: 100, left: 50, bottom: 100, right: 50))
        window.addSubview(customView)
        
        // 4. 确保在最上层(可选,新添加的子视图默认在上层)
        window.bringSubview(toFront: customView)
    } 
}

额外说明

  • 如果你的App支持iPad多窗口场景,上面的Window获取方式会准确拿到当前用户正在操作的活跃窗口。
  • 若偏好使用Auto Layout代替frame,可以在将customView添加到Window后,设置customView.translatesAutoresizingMaskIntoConstraints = false,再添加对应的约束即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:22:21