【问题标题】:Table view plays videos in other cells while scrolling down表格视图在向下滚动时播放其他单元格中的视频
【发布时间】:2017-04-06 05:38:30
【问题描述】:

以下是我尝试通过创建自定义控件来播放视频的代码。

点击播放按钮后,表格视图中的视频会播放,但它也会在播放视频的当前单元格的第三个单元格上播放。

在移动到第三个单元格并单击那里的播放按钮时,它会播放正确的视频,但同样的视频稍后会播放两个单元格。

我怎样才能克服这个问题。任何帮助将不胜感激。

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
    }
}

视图控制器类

var cell : 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!)
            let 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)
            }
        }
    }

【问题讨论】:

  • 单元格被重复使用,因此您在滚动时会多次添加点击处理程序。您应该在单元类本身中处理点击,并通过委托模式或闭包通知 tableview 控制器; stackoverflow.com/questions/28659845/…
  • 我已经实现了你提到的上述方法。但同样的问题仍然存在。 @Paulw11

标签: ios swift uitableview avplayer avplayerlayer


【解决方案1】:

你需要实现:

prepareForReuse()

在您的单元格上,然后在其中将 AVPlayer 告诉 pausereplaceCurrentItemnil 或新项目

【讨论】:

    【解决方案2】:

    您的表格视图单元格被重复使用,这就是您面临此类问题的原因。

    每次在 cellForRow:delegate 中时,使用一些布尔值或重置视频来管理它。

    【讨论】:

      【解决方案3】:

      最好将 cell?.playButton.addTarget(self, action: #selector(TrendViewController.onTapPlayButton), for: .touchUpInside) 放在单元格启动之前。

      在您的情况下,您可以将“cell?.playButton.addTarget(self, action: #selector(TrendViewController.onTapPlayButton)”放在这部分中,如下所示: 如果单元格 == nil { 单元格 = ViewTableCell(样式:UITableViewCellStyle.default,reuseIdentifier:resusableIdentifier) 单元格?.playButton.addTarget(自我,动作:#selector(TrendViewController.onTapPlayButton) } 对我来说,我会覆盖单元类中的initial方法并在里面做所有事情。

      【讨论】:

        猜你喜欢
        • 2023-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-06
        相关资源
        最近更新 更多