Adr*_*rro 1 xcode avplayer uicollectionview uicollectionviewcell swift
我正在使用从 Firebase 加载的 URL 填充集合视图。但是当我退出视图或向上滚动集合视图时,我无法让视频暂停。当我使用导航控制器返回时,我仍然可以听到后台播放的视频。然后当我再次进入视图时,视频开始播放,但第一个从未完成。
这是我的视图控制器。有小费吗?谢谢你!我还是 Swift 的新手,所以请原谅我的无知。
import UIKit
import AVKit
import AVFoundation
import Firebase
import FirebaseDatabase
import SDWebImage
class ComedyViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
var avPlayer = AVPlayer()
var avPlayerLayer = AVPlayerLayer()
@IBOutlet weak var comedyCollectionView: UICollectionView!
var comedyVideoArray = [ComedyModel]()
var comedyDBRef: DatabaseReference! {
return Database.database().reference().child("comedy")
}
override func viewDidLoad() {
super.viewDidLoad()
loadComedyDB()
}
func loadComedyDB() {
comedyDBRef.observe(DataEventType.value, with: { (snapshot) in
if snapshot.childrenCount > 0 {
self.comedyVideoArray.removeAll()
for comedyData in snapshot.children.allObjects as! [DataSnapshot] {
let comedyObject = comedyData.value as? [String: AnyObject]
let comedyPostTitle = comedyObject?["title"]
let comedyPostDescription = comedyObject?["description"]
let comedyArticleLink = comedyObject?["link"]
let comedyVideoUrl = comedyObject?["url"]
let allComedyData = ComedyModel(title: comedyPostTitle as! String?, description: comedyPostDescription as! String?, link: comedyArticleLink as! String?, url: comedyVideoUrl as! String?)
self.comedyVideoArray.append(allComedyData)
self.comedyCollectionView.reloadData()
}
}
})
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print(comedyVideoArray.count)
return comedyVideoArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cellB = comedyCollectionView.dequeueReusableCell(withReuseIdentifier: "comedyCell", for: indexPath) as! ComedyCollectionViewCell
let data = comedyVideoArray[indexPath.row]
let item = AVPlayerItem(url: URL(string: data.url!)!)
self.avPlayer = AVPlayer(playerItem: item)
self.avPlayer.actionAtItemEnd = .none
self.avPlayerLayer = AVPlayerLayer(player: self.avPlayer)
self.avPlayerLayer.videoGravity = .resizeAspectFill
self.avPlayerLayer.frame = CGRect(x: 0, y: 0, width: cellB.frame.size.width, height: cellB.frame.size.height / 2)
cellB.videoView.layer.addSublayer(self.avPlayerLayer)
self.avPlayer.play()
//cellB.videoView.sd_setImage(with: URL(string: data.link!), placeholderImage: UIImage(named: "1"))
return cellB
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if collectionView == self.comedyCollectionView {
self.avPlayer.pause()
}
}
}
Run Code Online (Sandbox Code Playgroud)
有几个问题:
UICollectionViewcellForItemAt在显示新单元格之前调用,这意味着旧单元格仍然可见。现在,当您将新单元出列时,您正在将指针avPlayer更改为新实例,AVPlayer这样当您暂停视频时,您实际上是在调用pause()新视频。旧的继续播放(在当时仍然可见的单元格中)。
AVPlayer每次UICollectionView调用 时,您都会向单元格添加一个实例cellForItemAt。但是UICollectionView尝试重用那些不再可见的单元格,因此您最终可以AVPlayer在每个单元格中使用很多s。为避免这种情况,您应该查看如何prepareForReuse在单元格上使用方法。我还建议您AVPlayer在单元格本身中创建(通过子类化UICollectionViewCell),然后将其设置为playerItemincellForItemAt方法。这样你就可以didEndDisplaying像这样暂停当前正在播放的视频(只是一个例子):
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if let comedyCell = cell as? ComedyCollectionViewCell {
comedyCell.avPlayer.pause()
}
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
3753 次 |
| 最近记录: |