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

Swift中为何两次调用addSublayer实现iOS截屏拦截?

iOS UIWindow扩展拦截截屏:两次addSublayer的作用解析

我发现一个用于iOS平台拦截截屏的UIWindow扩展方法,但不解为何要两次调用addSublayer。相关代码如下:

self.layer.superlayer?.addSublayer(textfield.layer)
textfield.layer.sublayers?.last?.addSublayer(self.layer)

希望了解这两行代码的含义及该实现的工作原理。


两行代码的含义

  • 第一行self.layer.superlayer?.addSublayer(textfield.layer):
    这里的self是UIWindow实例,self.layer.superlayer指向系统管理的窗口根容器层(UIApplication的主窗口容器)。这行代码将textfield的图层从原视图层级中剥离,直接挂载到系统窗口的根层级上,让它脱离原视图的约束。

  • 第二行textfield.layer.sublayers?.last?.addSublayer(self.layer):
    将当前UIWindow的内容图层(也就是原本显示App内容的图层)添加到textfield图层的最后一个子图层中,把原窗口内容变成textfield图层的子层级。

拦截截屏的工作原理

iOS系统截屏时会自动忽略UITextField的图层内容(出于隐私保护,系统默认不捕获输入框的敏感内容)。这两行代码通过重构图层层级,实现了截屏拦截:

最终的图层层级变为:
系统根层 → textfield.layer → 原window.layer

此时原窗口的内容虽然能正常显示在屏幕上,但它属于textfield图层的子层级。当系统触发截屏时,会跳过整个textfield的图层树,自然也就不会捕获到原窗口的内容,从而达到拦截截屏的效果。

为什么要分两次调用addSublayer?

如果直接将原window图层挂到textfield图层再添加到根层,可能会因为textfield自身的视图属性(比如默认的层级渲染规则)导致原窗口内容无法正常显示。分两步操作既能让textfield图层脱离原视图层级,又能保证原窗口内容作为子图层正常显示,同时被系统截屏逻辑识别为需要忽略的内容。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:07:16