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.layeras 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 addingself.layerto this, the entireself.layerwill 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
addSubviewto 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.layerwould 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:
This diagram makes it look as if
self.layerhave twosuperlayers when it actually doesn't.self.layer.superlayerdoesn't change whenself.layeris added as a sublayer oftextfield.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.