You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 19:56:17