iOS 11.0:如何隐藏通知中心及控制中心的WebView视频控制?
解决iOS 11.0中WebView播放视频隐藏控制中心/通知中心控件的方案
在iOS 11.0里,系统默认会给WebView中正在播放的媒体内容自动注册到控制中心和通知中心,要完全隐藏这些控件没有直接的WebView开关,但可以通过以下几种方案实现:
方案1:禁用远程控制事件接收
系统的媒体控制控件依赖远程控制事件的传递,你可以在承载WebView的ViewController中阻止App接收这类事件,让系统失去显示控件的触发源:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // 停止接收远程控制事件,系统就不会弹出媒体控件 UIApplication.shared.endReceivingRemoteControlEvents() }
⚠️ 注意:如果你的App还有其他需要远程控制的媒体内容,这个方法会影响它们,仅适合仅在当前WebView页面播放视频的场景。
方案2:注入JS+原生代码配合,避免触发系统媒体注册
通过JS控制视频始终以内嵌模式播放(不进入全屏),同时清空系统的媒体信息中心,让系统没有可显示的控制内容:
- 先配置WKWebView允许内嵌播放:
let config = WKWebViewConfiguration() // 允许视频在WebView内播放,不自动跳全屏 config.allowsInlineMediaPlayback = true // 如果需要视频自动播放,可设置这个属性 config.mediaTypesRequiringUserActionForPlayback = [] let webView = WKWebView(frame: view.bounds, configuration: config)
- 注入自定义JS修改视频属性并通知原生代码:
let hideControlsScript = WKUserScript(source: """ // 遍历所有视频元素,隐藏控件并强制内嵌播放 document.querySelectorAll('video').forEach(video => { video.controls = false; video.setAttribute('webkit-playsinline', ''); video.setAttribute('playsinline', ''); // 视频开始播放时,通知原生代码清空媒体信息 video.addEventListener('play', () => { window.webkit.messageHandlers.clearMediaInfo.postMessage(null); }); }); """, injectionTime: .atDocumentEnd, forMainFrameOnly: true) config.userContentController.addUserScript(hideControlsScript)
- 原生代码接收JS消息,清空系统媒体信息中心:
class YourWebViewController: UIViewController, WKScriptMessageHandler { override func viewDidLoad() { super.viewDidLoad() // 注册JS消息监听 config.userContentController.add(self, name: "clearMediaInfo") } func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { if message.name == "clearMediaInfo" { // 清空媒体信息,系统就不会显示控制控件 MPNowPlayingInfoCenter.default().nowPlayingInfo = nil } } }
方案3:替换WebView播放为原生AVPlayer(最可靠)
如果上面的方案效果不稳定,最彻底的方式是拦截WebView中的视频请求,改用原生AVPlayer播放,这样你能完全掌控所有系统行为:
- 拦截WebView中的视频链接:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { guard let url = navigationAction.request.url else { decisionHandler(.allow) return } // 判断是否是视频链接(可根据实际格式扩展) if url.pathExtension.lowercased() == "mp4" { // 用原生AVPlayer播放 let player = AVPlayer(url: url) let playerLayer = AVPlayerLayer(player: player) playerLayer.frame = webView.bounds webView.layer.addSublayer(playerLayer) player.play() // 配置音频会话,避免系统自动注册媒体控件 do { try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: .mixWithOthers) try AVAudioSession.sharedInstance().setActive(true) } catch { print(error.localizedDescription) } // 清空媒体信息 MPNowPlayingInfoCenter.default().nowPlayingInfo = nil decisionHandler(.cancel) return } decisionHandler(.allow) }
这种方式完全绕开WebView的媒体播放机制,你可以自定义所有播放逻辑,包括彻底隐藏系统级的媒体控件。
需要注意的是,iOS系统对媒体播放有严格的规范,部分方案可能在后续版本中有所调整,但在iOS 11.0中上述方案均有效。如果视频是HTTPS加载的,还要确保App的ATS配置允许加载对应资源。
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

