【问题标题】:Destroying scrolled Video cells in UICollectionView for TikTok-like functionality销毁 UICollectionView 中的滚动视频单元格以获得类似 TikTok 的功能
【发布时间】:2020-06-24 08:33:59
【问题描述】:

尝试通过全屏视频视图实现类似 TikTok 的功能 我对 swift 比较陌生,所以请原谅我 使用以下播放器https://github.com/piemonte/Player

当应用程序从后台移动到前台时,难以销毁早期的单元格实例,所有视频实例都开始播放

下面是我的视图控制器

import Player
import UIKit

class HomeViewController: UIViewController,UICollectionViewDelegateFlowLayout, UICollectionViewDataSource  {


    lazy var data :[homeModel] =  [
        homeModel(charge: 231,videoUrl:"vineet_179_2",currency:"rupees",tname:"Abhinav Mahajan",backgroundImage: #imageLiteral(resourceName: "3"),mDesc:"content,inthenight creator,Insad"),

        homeModel(charge: 2331,videoUrl:"vineet_179_2",currency:"rupees",tname:"Kuwber Singh",backgroundImage: #imageLiteral(resourceName: "3"),mDesc:"Footballer"),

        homeModel(charge: 231,videoUrl:"vineet_179_2",currency:"rupees",tname:"Harsh Singh",backgroundImage: #imageLiteral(resourceName: "3"),mDesc:"Footballer,Koolboi"),

        homeModel(charge: 11,videoUrl:"vineet_179_2",currency:"rupees",tname:"Sameeh Hola",backgroundImage: #imageLiteral(resourceName: "3"),mDesc:"Singer,Footballer"),

        homeModel(charge: 43231,videoUrl:"vineet_179_2",currency:"rupees",tname:"Baag Singh",backgroundImage: #imageLiteral(resourceName: "3"),mDesc:"Cricketer"),
    ]

     let collectionView:UICollectionView = {

        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        layout.minimumLineSpacing = 0

        layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)

        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.register(CustomCell.self, forCellWithReuseIdentifier: "cell")

        return cv
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.reloadData()
        self.title = "HomeView"          
        view.addSubview(collectionView)
        collectionView.backgroundColor = .red
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.showsVerticalScrollIndicator = false //
        collectionView.isPagingEnabled = true
        print("--colelction view --")


        if #available(iOS 11.0, *) {
            collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
            collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
            collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
            collectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
        } else {
            collectionView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor).isActive = true
            collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
            collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
            collectionView.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor).isActive = true //fix
        }



    }


    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionView.frame.width, height: collectionView.frame.height)
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return data.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            print("\(indexPath.row)")

            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
            cell.configure(with: data[indexPath.row])
            print("---cellForItemAt--")
            return cell
    }


    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {

        print("willDisplay")
    }


    func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        (cell as? CustomCell)?.player.pause()
        self.collectionView(collectionView, willDisplay: cell, forItemAt: indexPath)
    }


    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

        collectionView.visibleCells.forEach { cell in

            (cell as? CustomCell)?.player.playFromBeginning()
            print("scrollViewDidEndDecelerating")
        }
    } 
}

下面是自定义单元格

import UIKit
import Player


class CustomCell: UICollectionViewCell {


    let indianCurrency = "₹"
    var localUrl = Bundle.main.url(forResource:"", withExtension: "")


    public func configure(with model: homeModel) {
        self.localUrl = Bundle.main.url(forResource:"\(model.videoUrl)", withExtension: "mp4")
        self.player.url = localUrl
        self.button.setTitle("Book now for \(indianCurrency)\(model.charge)", for: .normal)
        self.nameLabel.text = ("\(model.tname)")

        self.marqueeLabel.text = ("\(model.mDesc)")
        print("cell configure called")
    }




    override func prepareForReuse() {
        super.prepareForReuse()
        self.localUrl = Bundle.main.url(forResource:"", withExtension: "MOV")
    }


    let player: Player = {
        let homePlay = Player()
        homePlay.playerView.playerBackgroundColor = .cyan
        homePlay.playerView.translatesAutoresizingMaskIntoConstraints = false
        homePlay.playbackLoops = true
        homePlay.url = Bundle.main.url(forResource: "re", withExtension: "mp4")
        return homePlay
    }()

    override init(frame: CGRect) {
        super.init(frame: .zero)
        setupView()

        setupPlayerView()
    }

    func setupView(){

        contentView.backgroundColor = .green
        contentView.addSubview(homeView)

        homeView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        homeView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
        homeView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
        homeView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
        homeView.backgroundColor = .green

    }

    func setupPlayerView(){
        homeView.addSubview(self.player.playerView)
        player.playerView.isHidden = false
        player.playerView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        player.playerView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
        player.playerView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
        player.playerView.heightAnchor.constraint(equalTo: contentView.heightAnchor).isActive = true
        player.playerView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
        let tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGestureRecognizer(_:)))
        tapGestureRecognizer.numberOfTapsRequired = 1
        player.view.addGestureRecognizer(tapGestureRecognizer)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

extension CustomCell {

    @objc func handleTapGestureRecognizer(_ gestureRecognizer: UITapGestureRecognizer) {
        switch self.player.playbackState {
        case .stopped:
            self.player.playFromBeginning()
            break
        case .paused:
            self.player.playFromCurrentTime()
            break
        case .playing:
            self.player.pause()
            break
        case .failed:
            self.player.pause()
            break
        }
    }
}

另外,这是我用来在本地播放视频的模型

struct homeModel {
    var charge:Int
    var videoUrl:String
    var currency:String
    var tname:String
    var backgroundImage: UIImage
    var mDesc:String
}

struct Video {

    let url: URL?

    init(url: URL?) {
        self.url = url
    }
}

谁能告诉我我错过了什么?

【问题讨论】:

    标签: swift xcode uicollectionview swift5 uicollectionviewflowlayout


    【解决方案1】:

    这里是关于AVPlayerhttps://www.craft.do/s/2Ic8O8TrFiK8L2的一些注意事项。

    现在我认为您不应该为您的应用使用 playerManager,而应该使用单个播放器。所以你不应该为每个单元创建一个播放器,最好只重用一个。

    【讨论】:

      猜你喜欢
      • 2020-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多