基於一些理由,我們可能會想要禁止使用者對我們的 app 做螢幕截圖。然而,iOS 並沒有提供這樣的功能。所幸,我們可以利用 UITextField 來達到此效果。
當將 UITextField.isSecureTextEntry 設為 true 之後,若使用者做螢幕截圖時,iOS UITextField 會將它的內容清空,來保護其內容不被截圖。因此,若我們將當前的 view 放進 UITextField,那當使用者做螢幕截圖時,UITextField 將會防止當前的 view 被截圖下來,如下程式碼(此程式碼源自於這裡)。
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) } } }
當我們用以上的程式碼保護當前的 view 之後,若使用者對此 view 做螢幕截圖的話,那他只會得到一個全部都是黑色的圖。
在使用 makeSecure() 保護 view 之後,你也可以隨時用 makeInsecure() 來取消保護此 view,如下程式碼。
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() } } }