2017-12-01 9 views
0

UITableViewにPodcastエピソードのリストを表示するアプリがあります。各セルは、UITableViewCellに拡張されたカスタムクラスで管理され、各セルには、そのエピソードの再生を制御するためのAVAudioPlayerという独自のインスタンスがあります。私がしようとしていることは、次です:イベントをUITableView外のUITableViewCellに渡す

エピソードの再生をクリックすると、別のエピソードが再生されている場合は停止し、新しいものを開始します。

私が達成したのは、UITableViewCellのプロトコルを作成して、再生ボタンを押すたびにイベントを発生させることでした。その後、そのプロトコルを私のUIViewControllerに実装し、最新の選択されたセルをcellForRowAt(私は最新のIndexPathを選択したままにします)とpauseメソッドを呼び出します。それはうまくいくように見えましたが、画面上に両方のセルが表示されていれば動作することに気付きました。画面にないcellForRowAtのセルを取得したい場合は、nullが返され、セルを更新することができず、同時に2つのセルがサウンドを再生することになります。ここで

は、セルのための私のコードです:

@IBAction func playbackButtonHandler(_ sender: UIButton) { 
    guard let audioPlayer = self.player else { 
     self.downloadAudio(forPodcast: podcast.id) 
     return 
    } 
    guard let cellIndex = indexPath else { return } 
    if (audioPlayer.isPlaying) { 
     audioPlayer.pause() 
     delegate?.onPauseActionSelected(forRow: cellIndex) 
    } else { 
     audioPlayer.play() 
     delegate?.onPlayActionSelected(forRow: cellIndex) 
    } 
    sender.isSelected = !sender.isSelected 
} 

とのViewController:

func onPlayActionSelected(forRow row: IndexPath) { 
    if let activeItem = self.activePodcast { 
     if row != activeItem { 
      guard let activeCell = self.tableView.cellForRow(at: activeItem) as? PodcastCell else { return } 
      activeCell.playbackButtonHandler(activeCell.playbackButton) 
     } 
    } 
    self.activePodcast = row 
} 

はこれを行うには良い方法はありますか?

EDIT:

はLarmeの提案を試してみましたが、同時にプレイする2つのオーディオトラックの問題の世話をしたAVAudioControllerためのViewControllerでシングルトンを作成しました。しかし、それでも、セルのコントロールを更新する方法については疑問が残っています。一時停止ボタンは、まだオーディオを再生しているかのように見えるためです。 説明のため画像を参照してください:

私は、もはやオーディオを再生する画面にないセルを持っています。次に、最初のセルで再生をクリックします。オーディオ停止と最初のセルに

I have a cell that is not in the screen anymore playing audio. Then I click play on the first cell. Audios stops and starts playing on the first cell

の再生を開始します今、私は一番下までスクロールし、セルはもうプレイしていないものの、一時停止ボタンが表示されたままです。私は

Now I scroll to the bottom and although the cell is not playing anymore, the pause button is still visible. I need a way to call the cell to change that button's state

+1

「おまかせ質問」をしないでください。各投稿を1つの問題にしておきます。別の問題がある場合は、追加の質問を投稿してください。 – rmaddy

+2

確かに 'cellForRow(at:)'は、セルが見えない場合はnilを返します。私がやることは、 "isPlaying"、 "currentProgression"を保持している配列のオブジェクトを編集する(indexControllerで取り出すことができる、ViewController、Singleton? "playAtTime"を実行するなど) – Larme

+0

@Larme私はそれを試みましたが、まだ目に見えないセルを更新するという問題が残っています。私はケースを説明するためにいくつかの画像で私の質問を更新した –

答えて

1

そのボタンの状態を変更するために、細胞を呼び出す方法は、SO 2つの問題のうちの1が同時に2つのオーディオを再生していること、固定である必要があります。今、2番目の問題は、UIをリフレッシュすることです。オーディオを再生しているセルに一時停止ボタンを表示し、最後に再生したセルの一時停止ボタンを再生ボタンに置​​き換えます。

onPlayActionSelectedメソッドでcellForRowを呼び出す必要はありません。代わりに、テーブルビューのcellForRowAtデリゲートメソッドにコードを記述します。そのセルが表示されていない場合は、直前のセルの一時停止ボタンをすぐに変更する必要はないため、ユーザーがその位置までスクロールした場合にのみ、一時停止ボタンを再生ボタンに変更する必要があるため、 。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    let activeCell = /* Deque your tableViewCell with its subclass */ 

    if let activeItem = self.activePodcast { 
     if indexPath.row == activeItem { 
      activeCell.buttonImageView.image = UIImage(named: "Play")! 
     }else { 
      activeCell.buttonImageView.image = UIImage(named: "Pause")! 
     } 
    } 

    return activeCell 
} 
関連する問題