iOS Swift实现应用截屏/录屏防护的开启与关闭方案咨询
iOS截屏/录屏防护的开关实现方案
你的现有代码通过利用UITextField.isSecureTextEntry的特性实现了截屏/录屏防护,要添加开关控制,核心是维护防护状态并支持移除防护层级,以下是具体实现步骤:
1. 持久化存储防护开关状态
用UserDefaults保存用户的设置,默认开启防护:
// 定义状态存储的Key private let screenCaptureProtectionKey = "ScreenCaptureProtectionEnabled" // 封装状态的读写 var isScreenCaptureProtectionEnabled: Bool { get { UserDefaults.standard.bool(forKey: screenCaptureProtectionKey) } set { UserDefaults.standard.set(newValue, forKey: screenCaptureProtectionKey) } } // 在App启动时初始化默认值(比如AppDelegate/SceneDelegate) func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 首次启动默认开启防护 if !UserDefaults.standard.object(forKey: screenCaptureProtectionKey) is Bool { isScreenCaptureProtectionEnabled = true } return true }
2. 改造防护逻辑,支持开启/关闭操作
通过关联对象保存防护用的UITextField,方便后续精准移除:
// 定义关联对象的Key private var protectionTextFieldAssociatedKey = "ProtectionTextFieldAssociatedKey" extension UIWindow { // 关联对象:存储当前防护用的UITextField private var protectionTextField: UITextField? { get { objc_getAssociatedObject(self, &protectionTextFieldAssociatedKey) as? UITextField } set { objc_setAssociatedObject(self, &protectionTextFieldAssociatedKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } // 开启截屏/录屏防护(复用你的原有逻辑) func enableScreenCaptureProtection() { guard protectionTextField == nil else { return } // 避免重复添加 let field = UITextField() let view = UIView(frame: CGRect(x: 0, y: 0, width: field.frame.width, height: field.frame.height)) let image = UIImageView(image: UIImage(named: "whiteImage")) image.frame = UIScreen.main.bounds field.isSecureTextEntry = true view.addSubview(image) addSubview(field) layer.superlayer?.addSublayer(field.layer) field.layer.sublayers?.last?.addSublayer(layer) field.leftView = view field.leftViewMode = .always protectionTextField = field // 保存到关联对象,供后续移除使用 } // 关闭截屏/录屏防护:移除所有相关层级和视图 func disableScreenCaptureProtection() { guard let field = protectionTextField else { return } // 恢复window的层级关联 layer.removeFromSuperlayer() field.layer.removeFromSuperlayer() // 移除视图 field.removeFromSuperview() // 清空关联对象 protectionTextField = nil } }
3. 设置菜单的开关回调处理
在设置页面的UISwitch控件回调中,根据开关状态切换防护:
// 假设设置页面的开关控件是@IBOutlet weak var protectionSwitch: UISwitch! @IBAction func protectionSwitchToggled(_ sender: UISwitch) { isScreenCaptureProtectionEnabled = sender.isOn guard let window = UIApplication.shared.windows.first else { return } if sender.isOn { window.enableScreenCaptureProtection() } else { window.disableScreenCaptureProtection() } }
4. 应用激活时恢复防护状态
在App从后台回到前台时,自动根据存储的状态恢复防护:
// iOS 13+:SceneDelegate的sceneDidBecomeActive方法 func sceneDidBecomeActive(_ scene: UIScene) { guard let windowScene = scene as? UIWindowScene, let window = windowScene.windows.first else { return } if isScreenCaptureProtectionEnabled { window.enableScreenCaptureProtection() } else { window.disableScreenCaptureProtection() } } // iOS 12及以下:AppDelegate的applicationDidBecomeActive方法 func applicationDidBecomeActive(_ application: UIApplication) { guard let window = application.windows.first else { return } if isScreenCaptureProtectionEnabled { window.enableScreenCaptureProtection() } else { window.disableScreenCaptureProtection() } }
内容的提问来源于stack exchange,提问作者Vikash Kumar Chaubey
相关产品推荐
相关产品推荐

