如何防止UIDocumentInteractionController中打开的文档被截屏?
解决UIDocumentInteractionController预览文档防截屏问题
UIDocumentInteractionController的预览视图由系统完全托管,常规的UIView安全层方案无法直接作用于它,你可以尝试以下几种可行方案:
方案1:改用QLPreviewController并添加安全层
QLPreviewController的视图层级可被我们获取和修改,能让安全层逻辑生效。
class PreviewVC: UIViewController, QLPreviewControllerDataSource, QLPreviewControllerDelegate { var documentURL: URL! func showDocument() { let previewController = QLPreviewController() previewController.dataSource = self previewController.delegate = self present(previewController, animated: true) } // QLPreviewController数据源实现 func numberOfPreviewItems(in controller: QLPreviewController) -> Int { return 1 } func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem { return documentURL as QLPreviewItem } // 预览出现后给视图加安全层 override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) presentedViewController?.view?.makeSecure() } // 复用你的安全层扩展 extension UIView { func makeSecure() { DispatchQueue.main.async { let secureField = UITextField() secureField.isSecureTextEntry = true self.addSubview(secureField) secureField.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true secureField.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true self.layer.superlayer?.addSublayer(secureField.layer) secureField.layer.sublayers?.first?.addSublayer(self.layer) } } } }
方案2:监听截屏通知,即时遮挡内容
如果坚持用UIDocumentInteractionController,可以监听系统截屏通知,触发时立即显示遮挡层,让截屏内容失效:
class PreviewVC: UIViewController, UIDocumentInteractionControllerDelegate { var docOpener: UIDocumentInteractionController! private var blurOverlay: UIView! override func viewDidLoad() { super.viewDidLoad() // 注册截屏通知 NotificationCenter.default.addObserver(self, selector: #selector(onScreenshotTaken), name: UIApplication.userDidTakeScreenshotNotification, object: nil) // 创建全屏遮挡层 blurOverlay = UIView(frame: view.bounds) blurOverlay.backgroundColor = .black blurOverlay.alpha = 0 blurOverlay.isUserInteractionEnabled = false view.addSubview(blurOverlay) } @objc private func onScreenshotTaken() { // 显示遮挡层,1秒后隐藏 UIView.animate(withDuration: 0.1) { self.blurOverlay.alpha = 1 } DispatchQueue.main.asyncAfter(deadline: .now() + 1) { UIView.animate(withDuration: 0.1) { self.blurOverlay.alpha = 0 } } } // 原文档展示逻辑 func showDocument(at path: URL) { docOpener = UIDocumentInteractionController(url: path) docOpener.delegate = self docOpener.presentPreview(animated: true) } func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController { return self } }
方案3:自定义文档渲染(针对PDF等格式)
如果文档是PDF或其他可自定义渲染的类型,直接用自定义视图(比如PDFView、WKWebView)渲染内容,再给视图加安全层:
class PreviewVC: UIViewController { var documentURL: URL! override func viewDidLoad() { super.viewDidLoad() let pdfView = PDFView(frame: view.bounds) pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight] if let pdfDoc = PDFDocument(url: documentURL) { pdfView.document = pdfDoc } view.addSubview(pdfView) // 给渲染视图加安全层 pdfView.makeSecure() } extension UIView { func makeSecure() { DispatchQueue.main.async { let secureField = UITextField() secureField.isSecureTextEntry = true self.addSubview(secureField) secureField.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true secureField.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true self.layer.superlayer?.addSublayer(secureField.layer) secureField.layer.sublayers?.first?.addSublayer(self.layer) } } } }
内容的提问来源于stack exchange,提问作者Aliaksandr Miatnikau
相关产品推荐
相关产品推荐

