如何在不同的 UICollectionView 单元格中显示不同的视频?
How to show different videos in different UICollectionView cells?
我试图在五个不同的 UICollectionView 单元格中显示 5 个不同的视频。这听起来很容易做到,使用 3 个单元格时它工作正常,但现在不知何故所有视频都在错误的单元格中。
这是一个丑陋的解决方案,但它以前有效,我想不出任何其他解决方案。
这里有五个不同的 AVPlayer 和 AVPlayerLayer 实例。
let theURL = Bundle.main.url(forResource:"summer", withExtension: "mp4")
let theURL2 = Bundle.main.url(forResource:"newyork", withExtension: "mp4")
let theURL3 = Bundle.main.url(forResource:"amber", withExtension: "mp4")
let theURL4 = Bundle.main.url(forResource:"luckywhite", withExtension: "mp4")
let theURL5 = Bundle.main.url(forResource:"coconut", withExtension: "mp4")
avPlayer = AVPlayer(url: theURL!)
avPlayerLayer = AVPlayerLayer(player: avPlayer)
avPlayerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
avPlayer.volume = 0
avPlayer.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer.currentItem)
avPlayer2 = AVPlayer(url: theURL2!)
avPlayerLayer2 = AVPlayerLayer(player: avPlayer2)
avPlayerLayer2.videoGravity = AVLayerVideoGravity.resizeAspectFill
avPlayer2.volume = 0
avPlayer2.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer2.currentItem)
avPlayer3 = AVPlayer(url: theURL3!)
avPlayerLayer3 = AVPlayerLayer(player: avPlayer3)
avPlayerLayer3.videoGravity = AVLayerVideoGravity.resizeAspectFill
avPlayer3.volume = 0
avPlayer3.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer3.currentItem)
avPlayer4 = AVPlayer(url: theURL4!)
avPlayerLayer4 = AVPlayerLayer(player: avPlayer4)
avPlayerLayer4.videoGravity = AVLayerVideoGravity.resizeAspectFill
avPlayer4.volume = 0
avPlayer4.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer4.currentItem)
avPlayer5 = AVPlayer(url: theURL5!)
avPlayerLayer5 = AVPlayerLayer(player: avPlayer5)
avPlayerLayer5.videoGravity = AVLayerVideoGravity.resizeAspectFill
avPlayer5.volume = 0
avPlayer5.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer5.currentItem)
这里我把视频放到了单元格中。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
switch indexPath.item {
case 0:
self.avPlayerLayer.frame = cell.image.layer.bounds
cell.image.layer.insertSublayer(self.avPlayerLayer, at: 0)
case 1:
self.avPlayerLayer2.frame = cell.image.layer.bounds
cell.image.layer.insertSublayer(self.avPlayerLayer2, at: 0)
case 2:
self.avPlayerLayer3.frame = cell.image.layer.bounds
cell.image.layer.insertSublayer(self.avPlayerLayer3, at: 0)
case 3:
self.avPlayerLayer4.frame = cell.image.layer.bounds
cell.image.layer.insertSublayer(self.avPlayerLayer4, at: 0)
default:
self.avPlayerLayer5.frame = cell.image.layer.bounds
cell.image.layer.insertSublayer(self.avPlayerLayer5, at: 0)
}
为什么不能正常工作?我认为在使用 indexPaths 时我所做的一切都是正确的。
单元格被重复使用,当你这样做时
self.avPlayerLayer4.frame = cell.image.layer.bounds
cell.image.layer.insertSublayer(self.avPlayerLayer4, at: 0)
所以考虑在插入之前清理它
cell.image.layer.sublayers?.forEach {
if [=11=] is AVPlayerLayer {
[=11=].removeFromSuperlayer()
}
}
它在最后面添加图层并显示之前添加的旧图层,而不是重复的代码,您需要编写一个函数 return 来自 url 的图层并将其添加
同时考虑使用像
这样的数组
var arr = [URL]()
并用它代替开关
我试图在五个不同的 UICollectionView 单元格中显示 5 个不同的视频。这听起来很容易做到,使用 3 个单元格时它工作正常,但现在不知何故所有视频都在错误的单元格中。
这是一个丑陋的解决方案,但它以前有效,我想不出任何其他解决方案。
这里有五个不同的 AVPlayer 和 AVPlayerLayer 实例。
let theURL = Bundle.main.url(forResource:"summer", withExtension: "mp4")
let theURL2 = Bundle.main.url(forResource:"newyork", withExtension: "mp4")
let theURL3 = Bundle.main.url(forResource:"amber", withExtension: "mp4")
let theURL4 = Bundle.main.url(forResource:"luckywhite", withExtension: "mp4")
let theURL5 = Bundle.main.url(forResource:"coconut", withExtension: "mp4")
avPlayer = AVPlayer(url: theURL!)
avPlayerLayer = AVPlayerLayer(player: avPlayer)
avPlayerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
avPlayer.volume = 0
avPlayer.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer.currentItem)
avPlayer2 = AVPlayer(url: theURL2!)
avPlayerLayer2 = AVPlayerLayer(player: avPlayer2)
avPlayerLayer2.videoGravity = AVLayerVideoGravity.resizeAspectFill
avPlayer2.volume = 0
avPlayer2.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer2.currentItem)
avPlayer3 = AVPlayer(url: theURL3!)
avPlayerLayer3 = AVPlayerLayer(player: avPlayer3)
avPlayerLayer3.videoGravity = AVLayerVideoGravity.resizeAspectFill
avPlayer3.volume = 0
avPlayer3.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer3.currentItem)
avPlayer4 = AVPlayer(url: theURL4!)
avPlayerLayer4 = AVPlayerLayer(player: avPlayer4)
avPlayerLayer4.videoGravity = AVLayerVideoGravity.resizeAspectFill
avPlayer4.volume = 0
avPlayer4.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer4.currentItem)
avPlayer5 = AVPlayer(url: theURL5!)
avPlayerLayer5 = AVPlayerLayer(player: avPlayer5)
avPlayerLayer5.videoGravity = AVLayerVideoGravity.resizeAspectFill
avPlayer5.volume = 0
avPlayer5.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer5.currentItem)
这里我把视频放到了单元格中。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
switch indexPath.item {
case 0:
self.avPlayerLayer.frame = cell.image.layer.bounds
cell.image.layer.insertSublayer(self.avPlayerLayer, at: 0)
case 1:
self.avPlayerLayer2.frame = cell.image.layer.bounds
cell.image.layer.insertSublayer(self.avPlayerLayer2, at: 0)
case 2:
self.avPlayerLayer3.frame = cell.image.layer.bounds
cell.image.layer.insertSublayer(self.avPlayerLayer3, at: 0)
case 3:
self.avPlayerLayer4.frame = cell.image.layer.bounds
cell.image.layer.insertSublayer(self.avPlayerLayer4, at: 0)
default:
self.avPlayerLayer5.frame = cell.image.layer.bounds
cell.image.layer.insertSublayer(self.avPlayerLayer5, at: 0)
}
为什么不能正常工作?我认为在使用 indexPaths 时我所做的一切都是正确的。
单元格被重复使用,当你这样做时
self.avPlayerLayer4.frame = cell.image.layer.bounds
cell.image.layer.insertSublayer(self.avPlayerLayer4, at: 0)
所以考虑在插入之前清理它
cell.image.layer.sublayers?.forEach {
if [=11=] is AVPlayerLayer {
[=11=].removeFromSuperlayer()
}
}
它在最后面添加图层并显示之前添加的旧图层,而不是重复的代码,您需要编写一个函数 return 来自 url 的图层并将其添加
同时考虑使用像
这样的数组var arr = [URL]()
并用它代替开关