iOS 16中SwiftUI列表内Video Player控件不显示问题求助
解决iOS 16中List内VideoPlayer控件不显示的问题
问题根源
你当前在List的行闭包内直接创建AVPlayer实例,iOS 16对List的视图复用和交互逻辑做了调整,这种临时创建的播放器实例无法正确触发控件渲染,同时每次行刷新都会重建播放器,还会引发不必要的性能损耗。
修复方案
- 独立管理AVPlayer实例:用
@State或@StateObject把播放器实例抽离到视图外部,保证实例稳定性,避免List刷新时重复创建。 - 调整交互与布局:添加
interactiveDismissDisabled()规避iOS 16的交互冲突,同时优化List行的布局约束。 - 规范生命周期逻辑:在
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
相关产品推荐
相关产品推荐

