Swift 取消更改控制器时,tableview 单元格内的 Avplayer 仍在播放
Swift Avplayer inside tableview cell still playing when dismissing changing controller
我在我的 tableview 单元格中配置了一个 avPlayer:
func createPlayer(url: URL) {
self.playerCell = AVPlayer(url: url)
self.videoContainerView.playerLayer.bounds = self.videoContainerView.bounds
self.videoContainerView.playerLayer.videoGravity = .resizeAspectFill
self.videoContainerView.playerLayer.player = playerCell
playerCell?.play()
}
而不是在用户单击按钮时调用此函数
@IBAction func playBtnPressed(_ sender: Any) {
if let videoUrlString = post?.mediaUrl, let url = URL(string: videoUrlString) {
createPlayer(url: url)
}
playBtn.isHidden = true
}
在我的 tableview 控制器中,只要单元格不再显示,我就可以停止播放器,如下所示:
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexPath) as? VideoCell else {return}
if cell.playerCell != nil {
if (cell.playerCell?.rate != 0) && (cell.playerCell?.error == nil) {
cell.playerCell?.pause()
cell.playerCell = nil
cell.playBtn.isHidden = false
}
}
}
我的问题是,如果我从 tableview 控制器切换到另一个控制器或关闭控制器,视频仍在播放。
我怎样才能停止播放器?
我需要索引路径来识别播放器,所以我无法调用 viewWillDisappear 中的函数。
希望有人能提供帮助,我已经尝试修复此问题 3 天...
谢谢!
- - - - - - - - - - - 更新
我试过这样做:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
guard let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell") as? VideoCell else {return}
if cell.playerCell != nil {
if (cell.playerCell?.rate != 0) && (cell.playerCell?.error == nil) {
cell.playerCell?.pause()
cell.playerCell = nil
cell.playBtn.isHidden = false
}
}
}
但是不行...
执行 viewWillDisappear
调用 visibleCells
并循环查找 VideoCell。每次你找到一个,告诉它停止播放,就像你已经拥有的代码一样。
一个更优雅的解决方案是覆盖 func prepareForReuse() 并在那里暂停播放器。删除它可能不是最好的方法,因为从一个单元格到另一个单元格,您可以替换 AVPlayer 实例中的当前项目,例如
avPlayer?.replaceCurrentItem(with: videoPlayerItem)
这对我有用
override func viewWillDisappear(_ animated: Bool) {
if let indexPath = self.tableView.indexPathsForVisibleRows {
for i in indexPath! {
let cell : myCustomCell = self.tableView.cellForRow(at: i) as! MyCustomCell
cell.mmPlayerLayer.player?.pause()
}
}
}
你可以像 viewWillDisappear 一样使用它
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let cell = cell as? YouTableViewCell else { return }
DispatchQueue.main.async {
cell.videoPlayer.player?.pause()
cell.videoPlayer.player = nil
cell.videoPlayer.layoutIfNeeded()
}
}
我在我的 tableview 单元格中配置了一个 avPlayer:
func createPlayer(url: URL) {
self.playerCell = AVPlayer(url: url)
self.videoContainerView.playerLayer.bounds = self.videoContainerView.bounds
self.videoContainerView.playerLayer.videoGravity = .resizeAspectFill
self.videoContainerView.playerLayer.player = playerCell
playerCell?.play()
}
而不是在用户单击按钮时调用此函数
@IBAction func playBtnPressed(_ sender: Any) {
if let videoUrlString = post?.mediaUrl, let url = URL(string: videoUrlString) {
createPlayer(url: url)
}
playBtn.isHidden = true
}
在我的 tableview 控制器中,只要单元格不再显示,我就可以停止播放器,如下所示:
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexPath) as? VideoCell else {return}
if cell.playerCell != nil {
if (cell.playerCell?.rate != 0) && (cell.playerCell?.error == nil) {
cell.playerCell?.pause()
cell.playerCell = nil
cell.playBtn.isHidden = false
}
}
}
我的问题是,如果我从 tableview 控制器切换到另一个控制器或关闭控制器,视频仍在播放。 我怎样才能停止播放器?
我需要索引路径来识别播放器,所以我无法调用 viewWillDisappear 中的函数。
希望有人能提供帮助,我已经尝试修复此问题 3 天...
谢谢! - - - - - - - - - - - 更新 我试过这样做:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
guard let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell") as? VideoCell else {return}
if cell.playerCell != nil {
if (cell.playerCell?.rate != 0) && (cell.playerCell?.error == nil) {
cell.playerCell?.pause()
cell.playerCell = nil
cell.playBtn.isHidden = false
}
}
}
但是不行...
执行 viewWillDisappear
调用 visibleCells
并循环查找 VideoCell。每次你找到一个,告诉它停止播放,就像你已经拥有的代码一样。
一个更优雅的解决方案是覆盖 func prepareForReuse() 并在那里暂停播放器。删除它可能不是最好的方法,因为从一个单元格到另一个单元格,您可以替换 AVPlayer 实例中的当前项目,例如 avPlayer?.replaceCurrentItem(with: videoPlayerItem)
这对我有用
override func viewWillDisappear(_ animated: Bool) {
if let indexPath = self.tableView.indexPathsForVisibleRows {
for i in indexPath! {
let cell : myCustomCell = self.tableView.cellForRow(at: i) as! MyCustomCell
cell.mmPlayerLayer.player?.pause()
}
}
}
你可以像 viewWillDisappear 一样使用它
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let cell = cell as? YouTableViewCell else { return }
DispatchQueue.main.async {
cell.videoPlayer.player?.pause()
cell.videoPlayer.player = nil
cell.videoPlayer.layoutIfNeeded()
}
}