Prevent Screenshots in iOS

Photo by Svitlana on Unsplash
Photo by Svitlana on Unsplash
For some reasons, we may want to prevent users from taking screenshots of our app. However, iOS does not provide such functionality. Fortunately, we can use UITextField to achieve this effect.

For some reasons, we may want to prevent users from taking screenshots of our app. However, iOS does not provide such functionality. Fortunately, we can use UITextField to achieve this effect.

After setting UITextField.isSecureTextEntry to true, if the user takes a screenshot, iOS UITextField will clear its content to protect its content from being screenshotted. Therefore, if we put the current view into UITextField, when the user takes a screenshot, UITextField will prevent the current view from being screenshotted, as shown in the following code (this code comes from here).

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.makeSecure()
    }
}

extension UIView {
    func makeSecure() {
        DispatchQueue.main.async {
            let field = UITextField()
            field.isSecureTextEntry = true
            self.addSubview(field)
            field.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
            field.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
            self.layer.superlayer?.addSublayer(field.layer)
            field.layer.sublayers?.first?.addSublayer(self.layer)
        }
    }
}

When we use the above code to protect the current view, if the user takes a screenshot of this view, he or she will only get a picture that is all black.

After using makeSecure() to protect the view, you can also use makeInsecure() to unprotect the view at any time, as shown in the following code.

class ViewController: UIViewController {
    @IBAction func onClick(_ sender: Any) {
        view.makeInsecure()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.makeSecure()
    }
}

var textField: UITextField?

extension UIView {
    func makeSecure() {
        DispatchQueue.main.async {
            let field = UITextField()
            field.isSecureTextEntry = true
            self.addSubview(field)
            field.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
            field.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
            self.layer.superlayer?.addSublayer(field.layer)
            field.layer.sublayers?.first?.addSublayer(self.layer)
            
            textField = field
        }
    }
    
    func makeInsecure() {
        DispatchQueue.main.async {
            guard let field = textField else { return }
            textField = nil
            field.layer.superlayer?.addSublayer(self.layer)
            field.removeFromSuperview()
            field.layer.removeFromSuperlayer()
        }
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like
Photo by Alex Alvarez on Unsplash
Read More

Dispatch Queue Tutorial

Grand Central Dispatch (GCD) provides efficient concurrent processing so that we don’t need to directly manage multiple threads. Its dispatch queues can execute tasks serially or concurrently.
Read More