You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS平台如何禁用屏幕捕获?触发屏幕捕获事件时如何显示模糊屏幕?

嘿,刚好在iOS上做过类似的安全需求,给你详细拆解下这两个问题的实现方案:

1. iOS平台禁用屏幕捕获功能的实现方式

iOS系统没有提供完全“禁止”用户触发截屏/录屏的方法,但可以通过系统API让捕获到的内容变成黑色或者不可见,达到保护机密内容的目的,主流有两种实现方式:

  • 全局窗口级保护:最简单的方式是把整个应用的UIWindow标记为安全窗口。系统会自动拦截屏幕捕获、录屏操作,捕获结果会显示为黑色(或系统默认的隐藏层)。
    代码示例(UIKit):

    // 在AppDelegate或SceneDelegate中设置
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        window?.isSecure = true
        return true
    }
    

    SwiftUI版本:

    struct ContentView: View {
        var body: some View {
            YourMainContent()
                .onAppear {
                    UIApplication.shared.windows.first?.isSecure = true
                }
        }
    }
    
  • 特定视图级保护:如果只需要保护某个机密视图,不需要全局禁用,可以给该视图添加一个安全图层:

    func setupSecureLayerForConfidentialView() {
        let secureLayer = CALayer()
        secureLayer.frame = confidentialView.bounds
        secureLayer.isSecure = true
        // 确保图层随视图大小变化
        confidentialView.layer.addSublayer(secureLayer)
        confidentialView.addObserver(self, forKeyPath: "bounds", options: .new, context: nil)
    }
    
    // 监听视图边界变化,更新安全图层大小
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "bounds", let view = object as? UIView {
            view.layer.sublayers?.filter { $0.isSecure }.first?.frame = view.bounds
        }
    }
    
2. 触发屏幕捕获事件时显示自定义模糊屏幕

如果不想直接让内容变黑,而是显示自定义的模糊提示层,可以通过监听系统通知来实现:

步骤1:注册屏幕捕获状态变化通知

在视图控制器的viewDidLoad或应用启动时注册通知:

override func viewDidLoad() {
    super.viewDidLoad()
    // 监听屏幕捕获状态变化
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(handleScreenCaptureStatusChange(_:)),
        name: UIScreen.capturedDidChangeNotification,
        object: nil
    )
}

步骤2:实现通知处理逻辑

在处理方法中判断当前是否处于捕获状态,然后显示/隐藏模糊层:

@objc private func handleScreenCaptureStatusChange(_ notification: Notification) {
    let isBeingCaptured = UIScreen.main.isCaptured
    if isBeingCaptured {
        showCustomBlurOverlay()
    } else {
        hideCustomBlurOverlay()
    }
}

步骤3:创建自定义模糊层

写两个方法来生成和移除模糊提示层:

private func showCustomBlurOverlay() {
    // 创建深色模糊效果
    let blurEffect = UIBlurEffect(style: .dark)
    let blurView = UIVisualEffectView(effect: blurEffect)
    blurView.frame = view.bounds
    blurView.tag = 999 // 标记方便后续查找移除
    blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight] // 适配屏幕旋转
    
    // 添加提示文字
    let warningLabel = UILabel()
    warningLabel.text = "⚠️ 禁止屏幕捕获,内容已隐藏"
    warningLabel.textColor = .white
    warningLabel.textAlignment = .center
    warningLabel.numberOfLines = 0
    warningLabel.translatesAutoresizingMaskIntoConstraints = false
    blurView.contentView.addSubview(warningLabel)
    
    // 约束提示文字到屏幕中心
    NSLayoutConstraint.activate([
        warningLabel.centerXAnchor.constraint(equalTo: blurView.centerXAnchor),
        warningLabel.centerYAnchor.constraint(equalTo: blurView.centerYAnchor),
        warningLabel.leadingAnchor.constraint(greaterThanOrEqualTo: blurView.leadingAnchor, constant: 20),
        warningLabel.trailingAnchor.constraint(lessThanOrEqualTo: blurView.trailingAnchor, constant: -20)
    ])
    
    view.addSubview(blurView)
    view.bringSubviewToFront(blurView)
}

private func hideCustomBlurOverlay() {
    if let blurView = view.viewWithTag(999) {
        blurView.removeFromSuperview()
    }
}

SwiftUI版本实现

如果用SwiftUI开发,可以通过onReceive监听通知,结合ZStack显示模糊层:

struct ContentView: View {
    @State private var isCaptured = false
    
    var body: some View {
        ZStack {
            // 你的机密内容视图
            ConfidentialContentView()
            
            // 捕获时显示的模糊层
            if isCaptured {
                CustomBlurOverlay()
                    .ignoresSafeArea()
            }
        }
        .onReceive(NotificationCenter.default.publisher(for: UIScreen.capturedDidChangeNotification)) { _ in
            isCaptured = UIScreen.main.isCaptured
        }
    }
}

// 自定义模糊Overlay
struct CustomBlurOverlay: View {
    var body: some View {
        VisualEffectView(effect: UIBlurEffect(style: .dark))
            .overlay(
                Text("⚠️ 禁止屏幕捕获,内容已隐藏")
                    .foregroundColor(.white)
                    .multilineTextAlignment(.center)
                    .padding()
            )
    }
}

// 包装UIKit的模糊效果到SwiftUI
struct VisualEffectView: UIViewRepresentable {
    var effect: UIVisualEffect?
    
    func makeUIView(context: Context) -> UIVisualEffectView {
        UIVisualEffectView()
    }
    
    func updateUIView(_ uiView: UIVisualEffectView, context: Context) {
        uiView.effect = effect
    }
}

注意事项

  • 即使设置了isSecure,也建议结合通知监听做额外处理,确保极端场景下的内容安全;
  • 测试时要覆盖系统截屏控制中心录屏两种场景,UIScreen.isCaptured会在两种情况下都触发变化;
  • 模糊层要确保覆盖整个屏幕,包括安全区域,避免出现漏显示的情况。

内容的提问来源于stack exchange,提问作者Nishant Kumbhare

火山引擎 最新活动