2017-12-01 5 views
0

UITableView에 Podcast 에피소드 목록을 표시하는 앱이 있습니다. 각 셀은 UITableViewCell을 확장하는 사용자 정의 클래스로 관리되며 각 셀에는 해당 에피소드 재생을 제어하는 ​​자체 인스턴스 인 AVAudioPlayer이 있습니다. 내가하려고하는 일은 다음입니다 :UITableView 외부의 UITableViewCell에 이벤트 전달

에피소드에서 재생을 클릭하면 재생중인 다른 에피소드가있는 경우 재생을 중지 한 다음 중지하고 새 것을 시작합니다.

내가 수행 한 작업은 재생 버튼을 누를 때마다 이벤트를 발생시키는 UITableViewCell에 프로토콜을 생성하는 것이 었습니다. 그런 다음 해당 프로토콜을 내 UIViewController에 구현하고 cellForRowAt (최신 선택한 IndexPath의 참조를 유지) 및 pause 메소드를 호출하여 최신 셀을 선택하십시오. 그것은 작동하는 것 같았지만 두 개의 셀이 모두 화면에 표시되면 작동한다는 것을 깨달았습니다. 화면에없는 cellForRowAt 인 셀을 가져올 때마다 메서드는 null을 반환하고 셀을 업데이트 할 수 없으므로 동시에 두 개의 셀이 사운드를 재생하게됩니다.

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 
} 

이 작업을 수행 할 수있는 더 나은 방법이 있나요 :

@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 :

여기 내 셀에 대한 코드입니까?

편집 :

이 Larme의 제안을 시도 함과 동시에 재생이 개 오디오 트랙의 문제를 처리했습니다 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

에서 재생이 시작됩니다. 나는 동시에 2 개 오디오를 재생하는, 그 버튼의 상태를 고정하는 두 문제 중

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

"보너스 질문"을하지 마십시오. 각 게시물을 하나의 문제로 유지하십시오. 다른 문제가 있으면 추가 질문을 게시하십시오. – rmaddy

+2

실제로'cellForRow (at :)'는 셀이 보이지 않으면 nil을 반환합니다. 내가 할 수있는 것은 하나의 플레이어 (ViewController, Singleton?에서)를 사용하고, "isPlaying", "currentProgression"을 유지하면서 배열의 객체를 편집하는 것입니다 ('indexPath'로 검색 할 수 있습니다. do "playAtTime") 등등. – Larme

+0

@Larme 나는 그것을 시도했지만 보이지 않는 셀을 업데이트하는 문제가 여전히 남아있다. 사건을 설명하기 위해 일부 이미지로 내 질문을 업데이트했습니다. –

답변

1

그래서 하나를 변경하려면 셀을 호출하는 방법이 필요합니다. 이제 두 번째 문제는 UI를 새로 고치는 것입니다. 오디오를 재생하는 셀에는 일시 중지 단추를 표시해야하며 재생 단추는 마지막으로 재생 된 셀의 일시 중지 단추를 대체합니다.

onPlayActionSelected 메서드에서 cellForRow를 호출 할 필요가 없습니다. 대신 tableview의 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 
} 
관련 문제