macOS:如何实现WKWebView中视频点击按钮全屏填充视图
视频全屏填充视图的实现方案
核心实现思路
- 建立SwiftUI视图与WebView的状态绑定,让按钮能触发全屏/退出全屏的状态切换
- 通过注入JavaScript控制网页内的视频元素,让其占满整个WebView视口
- 调整SwiftUI布局,在全屏状态下让WebView忽略安全区,隐藏多余控件
代码修改实现
1. 修改WebView组件(添加状态绑定与JS控制)
import SwiftUI import WebKit import AppKit struct WebView: NSViewRepresentable { typealias NSViewType = WKWebView let webView: WKWebView @Binding var isVideoFullscreen: Bool init(isVideoFullscreen: Binding<Bool>) { self._isVideoFullscreen = isVideoFullscreen webView = WKWebView(frame: .zero) webView.load(URLRequest(url: URL(string: "https://www.youtube.com/watch?v=FT3ODSg1GFE")!)) } func makeNSView(context: Context) -> WKWebView { webView.configuration.preferences.setValue(true, forKey: "fullScreenEnabled") webView.autoresizingMask = [.width, .height] return webView } func updateNSView(_ uiView: WKWebView, context: Context) { // 全屏状态切换时执行对应JS逻辑 if isVideoFullscreen { let fullscreenJS = """ const videos = document.querySelectorAll('video'); if (videos.length > 0) { const video = videos[0]; // 设置视频占满视口 video.style.width = '100%'; video.style.height = '100%'; video.style.objectFit = 'cover'; // 调整页面布局,隐藏多余元素 document.body.style.margin = '0'; document.body.style.padding = '0'; document.body.style.overflow = 'hidden'; // 调整视频父容器,确保层级最高 const parent = video.parentElement; if (parent) { parent.style.width = '100vw'; parent.style.height = '100vh'; parent.style.position = 'fixed'; parent.style.top = '0'; parent.style.left = '0'; parent.style.zIndex = '9999'; } video.play(); } """ uiView.evaluateJavaScript(fullscreenJS) { _, error in error.map { print("JS执行错误: \($0.localizedDescription)") } } } else { // 恢复原有布局 let resetJS = """ const videos = document.querySelectorAll('video'); if (videos.length > 0) { const video = videos[0]; video.style.width = ''; video.style.height = ''; video.style.objectFit = ''; document.body.style.margin = ''; document.body.style.padding = ''; document.body.style.overflow = ''; const parent = video.parentElement; if (parent) { parent.style.width = ''; parent.style.height = ''; parent.style.position = ''; parent.style.top = ''; parent.style.left = ''; parent.style.zIndex = ''; } } """ uiView.evaluateJavaScript(resetJS) { _, error in error.map { print("JS重置错误: \($0.localizedDescription)") } } } } }
2. 修改ContentView(添加状态控制与布局切换)
import SwiftUI import WebKit struct ContentView: View { @State private var isVideoFullscreen = false var body: some View { ZStack { if !isVideoFullscreen { VStack { HStack{ Button(isVideoFullscreen ? "退出全屏" : "Zoom Video") { isVideoFullscreen.toggle() } .padding() } WebView(isVideoFullscreen: $isVideoFullscreen) } .padding() } else { // 全屏状态下WebView占满整个视图 WebView(isVideoFullscreen: $isVideoFullscreen) .edgesIgnoringSafeArea(.all) // 添加角落退出按钮 Button("退出全屏") { isVideoFullscreen.toggle() } .padding() .background(Color.black.opacity(0.7)) .foregroundColor(.white) .cornerRadius(8) .position(x: 50, y: 50) } } } }
关键细节说明
- 状态绑定:通过
@Binding实现ContentView与WebView的状态同步,状态变化时自动触发JS执行 - JS适配:针对通用视频元素编写控制逻辑,若需适配特定网站(如YouTube),可调整元素选择器(比如通过类名定位视频容器)
- 布局切换:全屏状态下让WebView忽略安全区,隐藏顶部按钮栏,保证视频完全填充视图
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

