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

如何在WKWebView中监听视频全屏进入/退出事件并处理?

如何在WKWebView中检测视频全屏状态变化

嘿,针对你需要检测WKWebView里视频进入/退出全屏、并执行对应界面逻辑的需求,完全可以通过观察者(Notification Center)来实现,这是iOS里处理这类系统级事件的常规操作,另外还有JS交互的方案供你选择,下面给你详细拆解:

一、用系统通知(观察者)实现

1. 需要捕获的关键通知

你需要监听两个全局通知,它们是视频全屏状态变化时系统会自动发出的:

  • UIWindowDidBecomeVisibleNotification:视频进入全屏时,系统会创建一个单独的全屏UIWindow来播放视频,这个通知会触发
  • UIWindowDidBecomeHiddenNotification:视频退出全屏时,那个全屏窗口会被隐藏,对应这个通知

不过要注意,这两个通知是全局的,所以得在回调里加个判断,确保是WKWebView相关的视频窗口,避免误触发其他全屏事件。

2. 具体代码实现

注册通知观察者

在你的视图控制器的viewDidLoad里注册这两个通知:

override func viewDidLoad() {
    super.viewDidLoad()
    // 监听视频进入全屏
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(onVideoEnterFullScreen(_:)),
        name: UIWindow.didBecomeVisibleNotification,
        object: nil
    )
    // 监听视频退出全屏
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(onVideoExitFullScreen(_:)),
        name: UIWindow.didBecomeHiddenNotification,
        object: nil
    )
}

实现通知回调

在回调里判断窗口是否是AVPlayer的全屏播放窗口:

@objc private func onVideoEnterFullScreen(_ notification: Notification) {
    guard let window = notification.object as? UIWindow else { return }
    // 判断是否是苹果原生的全屏视频控制器窗口
    let avFullScreenVCClass = NSClassFromString("AVFullScreenViewController") ?? NSObject.self
    if window.rootViewController?.isKind(of: avFullScreenVCClass) ?? false {
        // 这里写你要执行的进入全屏逻辑,比如展示特定选项、修改界面
        print("视频进入全屏啦!")
    }
}

@objc private func onVideoExitFullScreen(_ notification: Notification) {
    guard let window = notification.object as? UIWindow else { return }
    let avFullScreenVCClass = NSClassFromString("AVFullScreenViewController") ?? NSObject.self
    if window.rootViewController?.isKind(of: avFullScreenVCClass) ?? false {
        // 这里写退出全屏后的逻辑
        print("视频退出全屏啦!")
    }
}

移除观察者(避免内存泄漏)

记得在视图控制器销毁时移除观察者:

deinit {
    NotificationCenter.default.removeObserver(self)
}

二、用JS交互实现(更精准)

如果你觉得全局通知不够精准,或者能控制网页内容,那可以通过注入JavaScript的方式,让网页主动通知Native视频的全屏状态变化:

1. 配置WKWebView并注入JS

在你的loadWebSite方法里添加脚本处理器和注入监听代码:

func loadWebSite() {
    let configuration = WKWebViewConfiguration()
    let preferences = WKPreferences()
    preferences.javaScriptCanOpenWindowsAutomatically = true
    configuration.preferences = preferences
    
    // 添加脚本消息处理器,用于接收网页发来的消息
    configuration.userContentController.add(self, name: "videoFullScreenHandler")
    
    // 注入JS代码,监听网页的全屏事件
    let fullScreenJS = """
    // 监听标准全屏事件
    document.addEventListener('fullscreenchange', function() {
        if (document.fullscreenElement) {
            window.webkit.messageHandlers.videoFullScreenHandler.postMessage('enter');
        } else {
            window.webkit.messageHandlers.videoFullScreenHandler.postMessage('exit');
        }
    });
    // 兼容Safari/webkit的全屏事件前缀
    document.addEventListener('webkitfullscreenchange', function() {
        if (document.webkitFullscreenElement) {
            window.webkit.messageHandlers.videoFullScreenHandler.postMessage('enter');
        } else {
            window.webkit.messageHandlers.videoFullScreenHandler.postMessage('exit');
        }
    });
    """
    let userScript = WKUserScript(
        source: fullScreenJS,
        injectionTime: .atDocumentEnd,
        forMainFrameOnly: true
    )
    configuration.userContentController.addUserScript(userScript)
    
    // 初始化并添加WKWebView到视图
    let webView = WKWebView(frame: view.bounds, configuration: configuration)
    view.addSubview(webView)
    // 加载你的网页...
    webView.load(URLRequest(url: URL(string: "your-web-url")!))
}

2. 实现WKScriptMessageHandler协议

让你的视图控制器遵守协议,处理网页发来的消息:

extension YourViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        guard let status = message.body as? String else { return }
        switch status {
        case "enter":
            // 视频进入全屏逻辑
            print("网页通知:视频进入全屏")
        case "exit":
            // 视频退出全屏逻辑
            print("网页通知:视频退出全屏")
        default:
            break
        }
    }
}

三、两种方案怎么选?

  • 系统通知方案:不需要修改网页代码,适合你无法控制网页内容的场景,但需要做窗口类型判断避免误触发
  • JS交互方案:只响应当前WKWebView内的视频事件,更精准,但需要网页支持(或者你能注入JS代码)

这两种方案都能完美满足你修改界面、展示特定选项的需求,根据你的实际场景选就行~

内容的提问来源于stack exchange,提问作者ÉnnOâman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:33:11