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

iOS 16中SwiftUI列表内Video Player控件不显示问题求助

解决iOS 16中List内VideoPlayer控件不显示的问题

问题根源

你当前在List的行闭包内直接创建AVPlayer实例,iOS 16对List的视图复用和交互逻辑做了调整,这种临时创建的播放器实例无法正确触发控件渲染,同时每次行刷新都会重建播放器,还会引发不必要的性能损耗。

修复方案

  1. 独立管理AVPlayer实例:用@State或@StateObject把播放器实例抽离到视图外部,保证实例稳定性,避免List刷新时重复创建。
  2. 调整交互与布局:添加interactiveDismissDisabled()规避iOS 16的交互冲突,同时优化List行的布局约束。
  3. 规范生命周期逻辑:在onAppear中触发播放,onDisappear中暂停,让播放器状态和视图生命周期同步。

修改后的代码示例

import SwiftUI
import AVKit

struct ContentView: View {
    // 用@State管理全局唯一的播放器实例
    @State private var player: AVPlayer?
    
    var body: some View {
        VStack {
            List(0..<2) { i in
                VStack {
                    if let player = player {
                        VideoPlayer(player: player)
                            .frame(maxWidth: .infinity, idealHeight: 320)
                            .padding(.horizontal, -20)
                            // 解决iOS16交互冲突,确保控件正常响应
                            .interactiveDismissDisabled()
                            .onAppear {
                                player.play()
                            }
                            .onDisappear {
                                player.pause()
                            }
                    }
                }
            }
            .onAppear {
                // 仅在视图初始化时创建一次播放器
                guard let url = URL(string: "http://wiu.ks-api.com/Content/file_3004.mp4") else { return }
                player = AVPlayer(url: url)
            }
        }
    }
}

如果需要每行对应不同视频,可通过数组管理播放器实例:

struct ContentView: View {
    // 数组管理多个播放器实例
    @State private var players: [AVPlayer?] = Array(repeating: nil, count: 2)
    // 视频URL列表
    private let videoURLs = [
        "http://wiu.ks-api.com/Content/file_3004.mp4",
        "http://wiu.ks-api.com/Content/file_3004.mp4" // 替换为不同URL
    ]
    
    var body: some View {
        VStack {
            List(0..<2) { i in
                VStack {
                    if let player = players[i] {
                        VideoPlayer(player: player)
                            .frame(maxWidth: .infinity, idealHeight: 320)
                            .padding(.horizontal, -20)
                            .interactiveDismissDisabled()
                            .onAppear {
                                player.play()
                            }
                            .onDisappear {
                                player.pause()
                            }
                    }
                }
            }
            .onAppear {
                // 初始化每个播放器实例
                for i in 0..<videoURLs.count {
                    guard let url = URL(string: videoURLs[i]) else { continue }
                    players[i] = AVPlayer(url: url)
                }
            }
        }
    }
}

额外提示

  • iOS 16优化了List的滚动和视图复用逻辑,临时创建的组件容易丢失交互状态,必须保证核心实例的生命周期和父视图绑定。
  • 如果控件仍不显示,可尝试给VideoPlayer添加.background(Color.black),避免透明背景导致的控件渲染异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:30:42