将kvc观察器添加到动态可重用单元格

问题描述:

我想将观察者添加到我的可重用单元格,问题是它添加了多个观察者。所以我想知道是否有任何解决方法,因为我真的需要这个观察者。将kvc观察器添加到动态可重用单元格

var player: AVPlayer? 

var post: Post? { 
    didSet { 
     updateView() 
    } 
} 

很多帖子是一个视频数组,每当帖子被设置为表视图上的一行时,就会调用它。

这就是为什么我不能在这个方法中添加观察者,因为它会设置多个观察者。

func updateView() { 
    if let videoUrlString = post?.videoURL { 
     let videoUrl = URL(string: videoUrlString) 
     player = AVPlayer(url: videoUrl!) 
     playerLayer = AVPlayerLayer(player: player) 
     playerLayer.frame = postVideoView.frame 
     playerLayer.frame.size.width = UIScreen.main.bounds.width 
     self.postVideoView.layer.addSublayer(playerLayer) 
     player?.play() 
     NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player?.currentItem, queue: nil, using: { (_) in 
      DispatchQueue.main.async { 
       self.player?.seek(to: kCMTimeZero) 
       self.player?.play() 
      } 
     }) 
} 

    self.updateLike(post: self.post!) 
} 

所以然后我试着在awakeFromNib()方法中设置它。

override func awakeFromNib() { 
    super.awakeFromNib() 
    player?.addObserver(self, forKeyPath: "currentItem.loadedTimeRanges", options: .new, context: nil) 
} 

但它没有工作,因为玩家尚未完全初始化。

这是我的观察器功能:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 
    if keyPath == "currentItem.loadedTimeRanges" { 
     if let duration = player?.currentItem?.duration { 
      let seconds = CMTimeGetSeconds(duration) 

      let secondsText = Int(seconds) % 60 
      let minutesText = String(format: "%02d", Int(seconds)/60) 
      videoLengthLabel.text = "\(minutesText):\(secondsText)" 
     } 
    } 
} 

我如何删除观察者:

func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "videoPostCell", for: indexPath) as! HomeTableViewCell 
    cell.playerLayer.removeFromSuperlayer() 
    cell.player?.pause() 
    cell.player?.isMuted = true 
    cell.delegate = self 
    cell.player?.removeObserver(self, forKeyPath: "currentItem.loadedTimeRanges") 
} 

我明白你的问题,如果你有问题删除观察者那么您可以在管理它下面委托方法UITableView

override func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    if let cell = cell as? CustomCell { 
     // Remove your observer here 
     // Stop Play Video 
    } 
} 

并保持您的cellForRowAtIndexPath原样。意味着创建观察者或ETC.

否则下面的链接将有助于你的情况。

1)Add and remove observer from multiple AVPlayerItem on UITableViewCell

2)Play video on UITableViewCell when it is completely visible

3)Embedding videos in a tableview cell

+0

那么,我应该添加观察者? –

+0

您可以在cellForRowAtIndexPath中添加观察者,它将在didEndDisplayingCell中删除 – Johnty

+0

我现在得到一个不同的错误消息: An -observeValueForKeyPath:ofObject:change:context:message已收到但未处理。 这是因为我添加了观察者UITableViewDelegate方法并在TableViewCell中处理它? 如果是的话我该如何解决这个问题? –