Табличное представление воспроизводит видео в других ячейках при прокрутке вниз
Ниже приведен код, в котором я пытаюсь воспроизвести видео, создавая собственные элементы управления.
При нажатии кнопки воспроизведения воспроизводится видео в табличном представлении, но оно также воспроизводится в третьей ячейке текущей ячейки, в которой воспроизводится видео.
Переместившись в третью ячейку и нажав там кнопку воспроизведения, он воспроизводит правильное видео, но снова то же видео воспроизводит две ячейки позже.
Как я могу преодолеть эту проблему. Любая помощь будет оценена.
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
}
}
Класс View Controller
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)
}
}
}
3 ответа
Вам необходимо реализовать:
prepareForReuse()
на вашей камере, то внутри это сказать AVPlayer
в pause
или же replaceCurrentItem
с nil
или новый предмет
Ваши ячейки таблицы повторно используются, вот почему вы столкнулись с такой проблемой.
Управляйте им с помощью некоторого логического значения или сбрасывайте видео каждый раз, когда в cellForRow: делегат.
Было бы лучше, чтобы вы поместили ячейку?.playButton.addTarget(self, action: #selector(TrendViewController.onTapPlayButton), для: .touchUpInside) до инициации ячейки.
В вашем случае вы можете поместить "cell?.PlayButton.addTarget(self, action: #selector(TrendViewController.onTapPlayButton)" "в эту часть следующим образом: if cell == nil { cell = ViewTableCell(style:UITableViewCellStyle.default, reuseIdentifier: resusableIdentifier) cell?.playButton.addTarget(self, action: #selector(TrendViewController.onTapPlayButton) }} Я бы переопределил метод initiate в классе ячеек и сделал бы все внутри.