簡體   English   中英

如何在不同的 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 $0 is AVPlayerLayer {
          $0.removeFromSuperlayer()
      }
   }

它在最后面添加圖層並在之前顯示舊添加的圖層,而不是重復的代碼,您需要編寫一個從 url 返回圖層的函數並添加它


Aslo考慮有一個像

var arr = [URL]()

並使用它代替開關

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM