2017-08-03 9 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) 
} 

しかし、まだ完全に初期化されていないため動作しませんでした。

これは私のobserver関数である:

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

これを読み込む別のエラーが発生しました。 -observeValueForKeyPath:ofObject:change:context:メッセージは受信されましたが、処理されませんでした。 これは、オブザーバのUITableViewDelegateメソッドを追加して、TableViewCellの内部で処理するためですか? もしそうなら、私はこれをどのように修正できますか? –

関連する問題