表视图单元格中的播放按钮显示错误的视频,因为它没有获得正确的单元格

时间:2017-04-03 18:02:57

标签: ios swift uitableview avplayer tableviewcell

我有一个表格视图控制器,我点击单元格中的按钮即可播放视频。

当我尝试在第一个单元格中播放视频时,它会在第二个单元格中播放视频。

我假设问题是因为它无法识别播放视频的正确单元格。

以下是我的代码

var cell : ViewTableCell?

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {


        let resusableIdentifier: String = "ViewControllerCell"
        cell = (tableView.dequeueReusableCell(withIdentifier: resusableIdentifier) as? ViewTableCell)

        if cell == nil {
            cell = ViewTableCell(style:UITableViewCellStyle.default, reuseIdentifier: resusableIdentifier)
        }

        cell?.videoName.text = ArtistFeeds.sharedInstance.videoFeeds[indexPath.row].videoTitle


        cell?.playButton.addTarget(self, action: #selector(TrendViewController.onTapPlayButton), for: .touchUpInside)

        cell?.playButton.tag = indexPath.row

        cell?.videoView.bringSubview(toFront: (cell?.videoName)!)
        return cell!
    }
    func onTapPlayButton(sender: subclassedUIButton){

        let indexOfButton = sender.indexPath
        let url = Bundle.main.path(forResource:ArtistFeeds.sharedInstance.videoFeeds[indexOfButton!].videoUrl, ofType:"mp4")

        let path = NSURL.fileURL(withPath: url!)
        let currentCell = trendTableView.cellForRow(at: indexOfButton) as! ViewTableCell
        currentCell.videoPlayerItem = AVPlayerItem.init(url: path)
        currentCell.startPlayback()

    }

当我在cellForRowAt indexPath函数中播放视频时,上面的代码正确播放视频

当我尝试点击按钮时,它会在不同的单元格中播放视频。

同样在onTapPlayButton()中我收到以下错误

无法转换'Int?'类型的值预期的参数类型'IndexPath'

任何帮助将不胜感激。谢谢。

以下是更新后的代码

class ViewTableCell: UITableViewCell {
var avPlayer: AVPlayer?
    var avPlayerLayer: AVPlayerLayer?
    var paused: Bool = false
    var videoPlayerItem: AVPlayerItem? = nil {
        didSet {

            avPlayer?.replaceCurrentItem(with: self.videoPlayerItem)
        }
    }

    var tapAction: ((ViewTableCell) -> Void)?

    @IBAction func playButtonAction(_ sender: UIButton) {
        tapAction?(self)
    }
func setupMoviePlayer(view:UIView){
        self.avPlayer = AVPlayer.init(playerItem: self.videoPlayerItem)
        avPlayerLayer = AVPlayerLayer(player: avPlayer)
        avPlayerLayer?.videoGravity = AVLayerVideoGravityResizeAspect
        avPlayer?.volume = 3
        avPlayer?.actionAtItemEnd = .none
        avPlayerLayer?.frame = view.bounds
        self.backgroundColor = .clear
        view.layer.insertSublayer(avPlayerLayer!, at: 0)

        let interval = CMTime(value: 1, timescale: 2)
        avPlayer?.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using :{ (progressTime) in
            let seconds = CMTimeGetSeconds(progressTime)

            if let duration = self.avPlayer?.currentItem?.duration{
                let durationSeconds = CMTimeGetSeconds(duration)
                self.videoSlider.value = Float(seconds/durationSeconds)
            }
        })

    }

    func stopPlayback(){
        self.avPlayer?.pause()
    }

    func startPlayback(){
        self.avPlayer?.play()
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        self.setupMoviePlayer(view: videoView)
        // Initialization code
    }
}

Ad ViewController类

var cell : TrendViewTableCell?
var currentCell = TrendViewTableCell()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        //MARK CellForRowAt


        let resusableIdentifier: String = "ViewControllerCell"
        cell = (tableView.dequeueReusableCell(withIdentifier: resusableIdentifier) as? ViewTableCell)

        if cell == nil {
            cell = ViewTableCell(style:UITableViewCellStyle.default, reuseIdentifier: resusableIdentifier)
        }

        cell?.videoName.text = ArtistFeeds.sharedInstance.videoFeeds[indexPath.row].videoTitle
        cell?.tapAction = { (cell) in

            self.onTapPlayButton(cell)

        }
        cell?.playButton.addTarget(self, action: #selector(TrendViewController.onTapPlayButton), for: .touchUpInside)
        return cell!
    }

func onTapPlayButton(_ selectedCell:ViewTableCell){

        if let index = self.trendTableView.indexPath(for: selectedCell){
            //put your code to execute here
            let url = Bundle.main.path(forResource:ArtistFeeds.sharedInstance.videoFeeds[index.row].videoUrl, ofType:"mp4")

            let path = NSURL.fileURL(withPath: url!)
            currentCell = tableView.cellForRow(at: index) as! ViewTableCell
            currentCell.videoPlayerItem = AVPlayerItem.init(url: path)
            let playImage = UIImage(named: "image_video_play") as UIImage?
            let pauseImage = UIImage(named: "image_video_pause") as UIImage?
            if currentCell.avPlayer?.rate == 1.0 {
                currentCell.stopPlayback()
                currentCell.playButton.setImage(playImage, for: .normal)

            } else {
                currentCell.startPlayback()
                currentCell.playButton.setImage(pauseImage, for: .normal)
            }
        }
    }

在上面更新的代码中,当我播放视频并滚动表格视图时,同一视频在视频当前正在播放的单元格的第三个单元格中播放。

2 个答案:

答案 0 :(得分:0)

要解决这种情况应该做的是在UITableViewCell中添加一个委托。确保协议继承" class",并使代表"弱"为了防止参考循环。您可以在cellForRowAt委托函数中设置委托,并在单元格内添加/删除播放按钮。每当按下按钮时,委托将通过传递电影的行号,ID或任何您认为适合您需要的内容来通知包含UITableView的类。然后,您可以打开正确的电影。

答案 1 :(得分:0)

这对我有用:

在你的手机课上:

class MyTVCell: UITableViewCell {

//var to hold closure that will be used for button action
var tapAction: ((MyTVCell) -> Void)?

@IBAction func myButtonAction(_ sender: AnyObject) {
        //use var defined above as a closure to execute
        tapAction?(self)
    }
}

在cellForRowAt中:

//setup cell button
        // Assign the tap action which will be executed when the user taps the UIButton
        cell?.tapAction = { (cell) in
//call your custom function
                self.mySelectedCell(cell)
            }

添加自定义功能:

//MARK: Button in Cell
func mySelectedCell(_ selectedCell:MyTVCell){
    //get cell index
    if let index = self.myTableView.indexPath(for: selectedCell){
        //put your code to execute here
    }
}