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

iOS WKWebView加载YouTube嵌入视频尺寸异常 仅显示1/4屏幕

问题场景
  • 业务需求:从服务端拉取YouTube视频链接,用户在UITableView列表选中对应单元格后,跳转至下级页面自动播放选中的视频。
  • 实现方案:采用WKWebView加载自定义HTML字符串的方式接入YouTube iFrame播放器,初始核心实现代码如下:
@IBOutlet weak var youtubeWebview: WKWebView!

override func viewDidLoad() {
    super.viewDidLoad()
    
    self.loadWebView()
}

func loadWebView() {
    var embedVideoHtml:String {
        return """
        <!DOCTYPE html>
        <html>
        <body>
        <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
        <div id="player"></div>

        <script>
        var tag = document.createElement('script');

        tag.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

        var player;
        function onYouTubeIframeAPIReady() {
        player = new YT.Player('player', {
        height: '\(youtubeWebview.frame.height)',
        width: '\(youtubeWebview.frame.width)',
        videoId: '\(videoLinkId)',
        events: {
        'onReady': onPlayerReady
        }
        });
        }

        function onPlayerReady(event) {
        event.target.playVideo();
        }
        </script>
        </body>
        </html>
        """
    }
    if !self.didLoadVideo {
        self.didLoadVideo = true
        self.youtubeWebview.loadHTMLString(embedVideoHtml, baseURL: nil)
    }
}
  • 异常表现:实际运行后视频仅占屏幕1/4大小,未达到「视频尺寸完全匹配承载WKWebView组件大小」的预期效果。
问题根因

两个核心问题导致尺寸异常:

  1. 加载时机错误:在viewDidLoad中调用加载逻辑时,WKWebView尚未完成Auto Layout布局,此时获取的youtubeWebview.frame.height/width是xib/Storyboard中的初始尺寸,不是最终渲染到屏幕上的实际尺寸,硬编码写入HTML的播放器宽高本身就是错误值。
  2. HTML缺少适配样式:自定义HTML未做全局样式重置,body、div标签默认存在内外边距,且播放器容器未设置撑满父视图的样式规则,进一步导致播放器尺寸偏小。
修复方案

按以下步骤调整即可解决尺寸问题:

  • 改写自定义HTML模板,增加全局样式重置,播放器宽高不硬编码数值,改用100%相对单位适配容器尺寸,修正后的HTML模板如下:
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        html, body {
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
        #player {
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <div id="player"></div>
    <script>
        var tag = document.createElement('script');
        tag.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

        var player;
        function onYouTubeIframeAPIReady() {
            player = new YT.Player('player', {
                height: '100%',
                width: '100%',
                videoId: '\(videoLinkId)',
                events: {
                    'onReady': onPlayerReady
                }
            });
        }

        function onPlayerReady(event) {
            event.target.playVideo();
        }
    </script>
</body>
</html>
  • 调整原生端加载时机,将WebView加载逻辑从viewDidLoad移至viewDidLayoutSubviews中,保留单次加载判断,确保WKWebView布局完成后再加载内容,同时关闭WebView滚动相关属性避免出现多余滚动条,修正后的原生代码参考:
@IBOutlet weak var youtubeWebview: WKWebView!

override func viewDidLoad() {
    super.viewDidLoad()
    // 关闭滚动、弹跳效果,避免出现多余交互
    youtubeWebview.scrollView.isScrollEnabled = false
    youtubeWebview.scrollView.bounces = false
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    loadWebView()
}

func loadWebView() {
    let embedVideoHtml = """
    // 替换为上述修正后的完整HTML模板
    """
    if !self.didLoadVideo {
        self.didLoadVideo = true
        self.youtubeWebview.loadHTMLString(embedVideoHtml, baseURL: nil)
    }
}
  • 检查WKWebView的约束设置,确保其上下左右约束与布局预期一致,不存在约束缺失导致WebView本身尺寸异常的问题。

内容的提问来源于stack exchange,提问作者Anilkumar iOS Developer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:12:05