2017-08-03 64 views
0

我想將觀察者添加到我的可重用單元格,問題是它添加了多個觀察者。所以我想知道是否有任何解決方法,因爲我真的需要這個觀察者。將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") 
} 

回答

0

我明白你的問題,如果你有問題刪除觀察者那麼您可以在管理它下面委託方法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中處理它? 如果是的話我該如何解決這個問題? –