iOS开发:隐藏而非销毁ViewController,恢复后台播放视频界面
嘿,这个场景太常见了!我来给你拆解两个核心问题:dismiss后视频继续播放,以及如何复用已有界面实例而不新建。咱们一步一步来解决:
解决iOS视频播放界面恢复与后台播放问题
第一步:先搞定dismiss后视频后台播放的问题
你现在遇到的后台播放问题,本质是dismiss界面时播放器没被暂停。可以在视频播放ViewController里重写生命周期方法,精准控制播放状态:
override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 只在界面被dismiss时暂停,避免push其他页面时误暂停播放 if isBeingDismissed { player?.pause() // 可选:保存当前播放进度,方便恢复界面时继续播放 if let currentTime = player?.currentTime().seconds { UserDefaults.standard.set(currentTime, forKey: "CurrentVideoPlaybackTime") } } }
第二步:保留视频VC实例,实现无新实例恢复
要做到不创建新实例恢复界面,核心是在TableViewController中持有视频播放VC的强引用,避免dismiss后实例被系统销毁:
- 在你的TableViewController中添加属性持有视频VC:
// 声明为可选类型,第一次使用时初始化 private var videoPlayerVC: VideoPlayerViewController?
- 在TableView的选中回调中,判断是否已有实例:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let targetVideo = yourVideoList[indexPath.row] // 替换成你的视频数据源 if let existingVC = videoPlayerVC { // 已有实例:更新视频源(如果用户选中了新视频) existingVC.updateVideo(with: targetVideo.url) // 恢复之前保存的播放进度 if let savedTime = UserDefaults.standard.double(forKey: "CurrentVideoPlaybackTime") { existingVC.player?.seek(to: CMTime(seconds: savedTime, preferredTimescale: 1)) } // 重新present已有的实例 present(existingVC, animated: true) { // 可选:自动恢复播放,根据你的需求调整 existingVC.player?.play() } } else { // 第一次使用:初始化视频VC并持有 let newVC = VideoPlayerViewController() newVC.videoURL = targetVideo.url videoPlayerVC = newVC present(newVC, animated: true) { newVC.player?.play() } } }
- 为视频VC添加更新视频的方法(支持切换不同视频):
// 在VideoPlayerViewController中实现 func updateVideo(with url: URL) { player?.pause() // 替换播放器资源 let asset = AVAsset(url: url) let playerItem = AVPlayerItem(asset: asset) player?.replaceCurrentItem(with: playerItem) }
额外优化:恢复界面时还原控件状态
在视频VC的viewWillAppear方法中,还原自定义控件的状态,让恢复体验更流畅:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) guard let player = player, let currentItem = player.currentItem else { return } // 更新进度条到当前播放位置 progressBar.setValue(Float(player.currentTime().seconds / currentItem.duration.seconds), animated: true) // 更新播放/暂停按钮状态 playPauseButton.setImage(player.isPlaying ? UIImage(systemName: "pause") : UIImage(systemName: "play"), for: .normal) }
内容的提问来源于stack exchange,提问作者JustMe
相关产品推荐
相关产品推荐

