I found an extension function to block screeenShot in iOS.
But I wounder to know why addSublayer twice.
self.layer.superlayer?.addSublayer(textfield.layer)
textfield.layer.sublayers?.last?.addSublayer(self.layer)
what's these code mean?
I can't figure out.
I need some explains to let me know how it works.
Thanks.
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)
}
}
This method of preventing screenshots uses the unique behaviour of text fields with isSecureTextEntry = true
. These text fields cannot be screenshotted. They appear black on screenshots.
This is why the code adds self.layer
as a sublayer of the text field's last sublayer. The text field's last sublayer happens to be the layer that doesn't get screenshotted (though I don't think this is guaranteed by the documentation). By adding self.layer
to this, the entire self.layer
will not appear in screenshots.
Of course, we haven't actually added the text field's layer to the rest of the layer hierarchy yet, similar to the common mistake of creating a view, and then forgetting to addSubview
to an existing view. At this point the text field is just some random thing in memory with nothing else knowing about it.
This is why we add the text field's layer as a sublayer of self.layer.superlayer
. Now the system actually knows the secure text field exists and prevents screenshots.
Note that we can't add it to self.layer
, because that would cause a cycle in the layers' relationships - self.layer
would be a child of itself, and at the same time, a parent of itself. Also, by adding as a sibling of the window's layer (instead of a sublayer of the window's layer), it also doesn't appear on the screen.
FYI, the layer hierarchy looks like this in the end:
the rest of the layer hierarchy
|
self.layer.superlayer
| \
| textfield.layer
| /
| /
| /
| /
self.layer
|
your views
This diagram makes it look as if self.layer
have two superlayer
s when it actually doesn't. self.layer.superlayer
doesn't change when self.layer
is added as a sublayer of textfield.layer
. The lines here are only showing the sublayer relationship - the layers on the bottom of the lines are sublayers of the layers on the top of the lines.