如何在 collectionView 中一次播放一个视频?
How to play one video at a time in a collectionView?
我正在构建一个类似于 TikTok 的应用程序,其中主要提要是一个 UICollectionView,每个单元格中都有一个视频。我的问题是多个视频会同时播放,我只想一次播放一个视频,具体取决于单元格是否在视图中。如果单元格不在视图中,我还希望视频暂停。
每个cell占满整个屏幕,collectionView开启了分页。
如果您曾经使用过 Instagram 或 TikTok,我希望功能相同。视频仅在单元格进入视图时播放,视频在单元格离开视图时暂停。如果您需要更多代码或信息,请告诉我,谢谢!
FeedController 中的相关代码如下:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! FeedCell
cell.delegate = self
cell.post = posts[indexPath.row]
if let videoUrl = posts[indexPath.row].videoUrl {
player = AVPlayer(url: videoUrl)
playerLayer = AVPlayerLayer(player: player)
playerLayer?.zPosition = -1
playerLayer?.frame = cell.contentView.frame
playerLayer?.videoGravity = .resizeAspectFill
cell.contentView.layer.addSublayer(playerLayer!)
player?.play()
cell.playerLayer = playerLayer
cell.player = player
}
return cell
}
这里是 FeedCell 的相关代码:
class FeedCell: UICollectionViewCell {
var post: Post?
var playerLayer: AVPlayerLayer?
var player: AVPlayer?
override func prepareForReuse() {
super.prepareForReuse()
playerLayer?.removeFromSuperlayer()
player?.pause()
}
}
您可以使用 collectionView(:willDisplay:forItemAt:) and collectionView(:didEndDisplaying:forItemAt:) 委托方法轻松实现此目的。
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
(cell as? FeedCell).player?.play()
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
(cell as? FeedCell).player?.pause()
}
注意: didEndDisplaying 只有在您的单元格完全从屏幕上消失后才会被调用。
我正在构建一个类似于 TikTok 的应用程序,其中主要提要是一个 UICollectionView,每个单元格中都有一个视频。我的问题是多个视频会同时播放,我只想一次播放一个视频,具体取决于单元格是否在视图中。如果单元格不在视图中,我还希望视频暂停。
每个cell占满整个屏幕,collectionView开启了分页。
如果您曾经使用过 Instagram 或 TikTok,我希望功能相同。视频仅在单元格进入视图时播放,视频在单元格离开视图时暂停。如果您需要更多代码或信息,请告诉我,谢谢!
FeedController 中的相关代码如下:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! FeedCell
cell.delegate = self
cell.post = posts[indexPath.row]
if let videoUrl = posts[indexPath.row].videoUrl {
player = AVPlayer(url: videoUrl)
playerLayer = AVPlayerLayer(player: player)
playerLayer?.zPosition = -1
playerLayer?.frame = cell.contentView.frame
playerLayer?.videoGravity = .resizeAspectFill
cell.contentView.layer.addSublayer(playerLayer!)
player?.play()
cell.playerLayer = playerLayer
cell.player = player
}
return cell
}
这里是 FeedCell 的相关代码:
class FeedCell: UICollectionViewCell {
var post: Post?
var playerLayer: AVPlayerLayer?
var player: AVPlayer?
override func prepareForReuse() {
super.prepareForReuse()
playerLayer?.removeFromSuperlayer()
player?.pause()
}
}
您可以使用 collectionView(:willDisplay:forItemAt:) and collectionView(:didEndDisplaying:forItemAt:) 委托方法轻松实现此目的。
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
(cell as? FeedCell).player?.play()
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
(cell as? FeedCell).player?.pause()
}
注意: didEndDisplaying 只有在您的单元格完全从屏幕上消失后才会被调用。