我发现了 iOS 中屏蔽 screenShot 的扩展功能。
但我更不知道为什么 addSublayer 两次。
self.layer.superlayer?.addSublayer(textfield.layer)
textfield.layer.sublayers?.last?.addSublayer(self.layer)
这些代码是什么意思?
我想不通。
我需要一些解释来让我知道它是如何工作的。
谢谢。
extension UIWindow {
func makeSecure() {
let textfield = UITextField()
textfield.isSecureTextEntry = true
self.addSubview(textfield)
textfield.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
textfield.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
self.layer.superlayer?.addSublayer(textfield.layer)
textfield.layer.sublayers?.last?.addSublayer(self.layer)
}
}
这种防止屏幕截图的方法使用带有
isSecureTextEntry = true
的文本字段的独特行为。这些文本字段无法进行屏幕截图。它们在屏幕截图上显示为黑色。
这就是代码添加
self.layer
作为文本字段最后一个子层的子层的原因。文本字段的最后一个子层恰好是没有屏幕截图的层(尽管我认为文档不能保证这一点)。通过添加 self.layer
,整个 self.layer
将不会出现在屏幕截图中。
当然,我们实际上还没有将文本字段的图层添加到图层层次结构的其余部分,类似于创建视图然后忘记
addSubview
添加到现有视图的常见错误。此时,文本字段只是内存中的一些随机事物,没有其他任何信息。
这就是为什么我们将文本字段的图层添加为
self.layer.superlayer
的子图层。现在系统实际上知道安全文本字段存在并阻止屏幕截图。
请注意,我们不能将其添加到
self.layer
,因为这会导致层关系中的循环 - self.layer
将是其自身的子级,同时也是其自身的父级。此外,通过添加为窗口图层的同级(而不是窗口图层的子图层),它也不会出现在屏幕上。
仅供参考,图层层次结构最终看起来像这样:
everything on the screen
|
self.layer.superlayer
/ \
self.layer textfield.layer
| |
your views self.layer
|
your views