当UICollectionViewCell不在视图时尝试暂停视频

时间:2018-06-18 22:25:05

标签: swift xcode uicollectionview uicollectionviewcell avplayer

我正在使用从Firebase加载的网址填充集合视图。但是当我退出视图或向上滚动集合视图时,我无法暂停视频。当我使用导航控制器返回时,我仍然可以听到在后台播放的视频。然后,当我再次进入视图时,视频开始播放,但第一个视频从未完成。

这是我的视图控制器。有小费吗?谢谢!我还是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()
        }
    }
}

1 个答案:

答案 0 :(得分:1)

有几个问题:

  1. [Unit] Description=OpenLDAP Server Daemon After=syslog.target network-online.target Documentation=man:slapd Documentation=man:slapd-config Documentation=man:slapd-hdb Documentation=man:slapd-mdb Documentation=file:///usr/share/doc/openldap-servers/guide.html [Service] Type=forking ExecStartPre=/usr/libexec/openldap/check-config.sh ExecStart=/usr/sbin/slapd -u ldap -h "ldap:/// ldaps:/// ldapi:///" [Install] WantedBy=multi-user.target Alias=openldap.service 在显示新单元格之前调用[root@localhost operations]# ll /etc/openldap/slapd.d/cn\=config total 24 drwxr-x---. 2 ldap ldap 4096 Jun 15 23:00 'cn=schema' -rw-------. 1 ldap ldap 378 Jun 15 23:00 'cn=schema.ldif' -rw-------. 1 ldap ldap 513 Jun 15 23:00 'olcDatabase={0}config.ldif' -rw-------. 1 ldap ldap 412 Jun 15 23:00 'olcDatabase={-1}frontend.ldif' -rw-------. 1 ldap ldap 562 Jun 15 23:00 'olcDatabase={1}monitor.ldif' -rw-------. 1 ldap ldap 609 Jun 15 23:00 'olcDatabase={2}mdb.ldif' [root@localhost operations]# ll /var/lib/| grep ldap drwx------. 2 ldap ldap 4096 Jun 19 00:30 ldap [root@localhost operations]# ll /var/lib/ldap/ total 0 -rw-------. 1 ldap ldap 8192 Jun 19 00:30 lock.mdb ,这意味着旧单元格仍然可见。现在,当您将新单元格出列时,您将指针UICollectionView更改为cellForItemAt的新实例,这样当您暂停视频时,您实际上正在调用avPlayer新视频视频。旧的继续播放(在当时仍然可见的单元格中)。

  2. 每次AVPlayer调用pause()时,您都会向该单元格添加AVPlayer的实例。但是UICollectionView会尝试重复使用那些不再可见的单元格,因此您可以在每个单元格中使用大量cellForItemAt个。为避免这种情况,您应该查看如何在单元格上使用UICollectionView方法。我还建议您在单元格中创建AVPlayer(通过继承prepareForReuse),然后在AVPlayer方法中设置其UICollectionViewCell。通过这种方式,您可以暂停当前正在播放的playerItem方法中的视频(仅作为示例):

    cellForItemAt