iOS 17下isSecureTextEntry防截图方案失效,求替代方案
iOS 17 替代
isSecureTextEntry的防截图方案 之前基于UITextField.isSecureTextEntry的层嵌套防截图方案在iOS 17中已失效,且DRM方案性能表现不佳,以下是几种可行的替代方案:
方案1:系统原生全局防捕获控制
利用UIWindowScene的isScreenCaptureEnabled属性,可直接禁用当前场景的屏幕录制与截图功能,无额外性能开销。
// 禁用屏幕捕获 if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene { scene.isScreenCaptureEnabled = false } // 恢复屏幕捕获(完成敏感操作后记得调用) if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene { scene.isScreenCaptureEnabled = true }
适用场景:需要对整个页面或应用全局禁用屏幕捕获的场景,实现简单,但会影响当前场景下所有内容的捕获权限。
方案2:监听截图通知动态隐藏敏感内容
通过监听系统截图通知,在用户触发截图瞬间隐藏敏感视图,截图完成后恢复显示,避免敏感内容被捕获。
// 注册截图通知(建议在视图控制器viewDidLoad中调用) NotificationCenter.default.addObserver(self, selector: #selector(handleScreenshotTriggered), name: UIApplication.userDidTakeScreenshotNotification, object: nil) @objc private func handleScreenshotTriggered() { // 立即隐藏敏感视图 sensitiveView.isHidden = true // 延迟恢复,确保截图流程完成 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.sensitiveView.isHidden = false } } // 记得在视图销毁时移除通知 deinit { NotificationCenter.default.removeObserver(self) }
适用场景:仅需保护局部敏感视图的场景,实现成本低,对性能影响极小,但无法完全阻止用户触发截图操作。
方案3:使用Metal视图精准控制捕获权限
通过MTKView的isCaptureEnabled属性,可单独禁用某个视图的屏幕捕获能力,适合需要精准控制且对性能要求较高的场景。
import MetalKit // 创建MTKView并配置防捕获 func setupSecureMetalView() { guard let device = MTLCreateSystemDefaultDevice() else { print("Metal设备不可用") return } let secureView = MTKView(frame: CGRect(x: 50, y: 200, width: 300, height: 100)) secureView.device = device secureView.isCaptureEnabled = false // 禁用该视图的屏幕捕获 secureView.backgroundColor = .white // 实现Metal渲染逻辑,将敏感内容绘制到视图中 secureView.delegate = self view.addSubview(secureView) } // 实现MTKViewDelegate协议完成渲染 extension YourViewController: MTKViewDelegate { func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {} func draw(in view: MTKView) { guard let commandBuffer = view.device?.makeCommandQueue()?.makeCommandBuffer(), let renderPassDescriptor = view.currentRenderPassDescriptor, let drawable = view.currentDrawable else { return } let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) // 在这里添加你的敏感内容渲染代码(如绘制文本、图形等) commandEncoder?.endEncoding() commandBuffer.present(drawable) commandBuffer.commit() } }
适用场景:需要对特定视图单独防捕获,且具备Metal开发能力的场景,性能表现优异,可灵活定制渲染内容。
内容的提问来源于stack exchange,提问作者Colin Jiaxi Lv
相关产品推荐
相关产品推荐

