AVPlayerViewController仅发声无画面,present调用报错求助
问题分析与解决方案
核心问题
UITableViewCell不属于UIViewController类型,因此没有present方法,直接调用self.present会触发报错。- 通过
self.window?.rootViewController?.present弹出播放器时出现有声音无画面,是因为单元格生命周期不稳定,直接在Cell中持有并弹出AVPlayerViewController会导致视图层级异常或控制器实例被意外释放。
正确解决方案:将播放逻辑移至ViewController
单元格仅负责触发播放事件,实际的播放器弹出逻辑交给对应的UITableViewController处理,符合iOS开发的职责分离原则。
1. 修改VideoPostCell代码
import UIKit import AVFoundation import AVKit class VideoPostCell: UITableViewCell { @IBOutlet weak var thumbnailImageView: UIImageView! static let identifier: String = "VideoPostCell" static func nib() -> UINib{ return UINib(nibName: "VideoPostCell", bundle: nil) } var playURL: URL? // 添加闭包,用于通知ViewController触发播放 var didTapToPlay: ((URL) -> Void)? override func awakeFromNib() { super.awakeFromNib() } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) guard selected, let safeURL = playURL else { return } // 触发闭包,传递视频URL didTapToPlay?(safeURL) } }
2. 在对应的TableViewController中处理播放
class VideoListViewController: UITableViewController { // 假设你的视频URL数组 var videoURLs: [URL] = [] override func viewDidLoad() { super.viewDidLoad() tableView.register(VideoPostCell.nib(), forCellReuseIdentifier: VideoPostCell.identifier) } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: VideoPostCell.identifier, for: indexPath) as! VideoPostCell let url = videoURLs[indexPath.row] cell.playURL = url // 绑定闭包,处理播放逻辑 cell.didTapToPlay = { [weak self] videoURL in let player = AVPlayer(url: videoURL) let playerVC = AVPlayerViewController() playerVC.player = player // 从当前ViewController弹出播放器,确保视图层级正确 self?.present(playerVC, animated: true) { player.play() } } return cell } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 200 // 根据需求调整高度 } }
关于self.window?.rootViewController?.present的说明
该方法在当前iOS版本中语法上是可用的,但不推荐使用:
- 若rootViewController不是当前最上层的控制器(比如存在导航控制器、tabBar控制器或已弹出的弹窗),会导致播放器弹出层级异常。
- 单元格的生命周期由TableView管理,直接在Cell中持有
AVPlayerViewController容易引发内存问题或视图加载异常,这也是你出现有声音无画面的核心原因。
内容的提问来源于stack exchange,提问作者Tony Yao
相关产品推荐
相关产品推荐

