【问题标题】:Pass events to UITableViewCell outside of UITableView将事件传递给 UITableView 之外的 UITableViewCell
【发布时间】:2017-12-01 15:33:19
【问题描述】:

我有一个应用程序,它在UITableView 上显示播客剧集列表。每个单元格都由扩展UITableViewCell 的自定义类管理,每个单元格都有自己的AVAudioPlayer 实例来控制剧集的播放。我想做的是下一个:

当我点击某一集的播放时,如果还有另一集正在播放,则停止播放,然后开始新的。

我所做的就是在UITableViewCell 上创建一个协议,只要按下播放按钮就会触发一个事件。然后在我的UIViewController 上实现该协议并使用cellForRowAt 获取最新选定的单元格(我保留了最新选定IndexPath 的引用)并调用暂停方法。这似乎有效,但后来我意识到它只有在两个单元格都在屏幕上可见时才有效。每当我想获取一个不在屏幕中的带有cellForRowAt 的单元格时,该方法返回 null 并且我无法更新该单元格,这导致两个单元格同时播放声音。

这是我的单元格代码:

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

有没有更好的方法来做到这一点?

编辑:

尝试了 Larme 的建议,并在 ViewController 中为 AVAudioController 创建了一个单例,以解决同时播放两个音轨的问题。但是,这仍然留下了如何更新单元格控件的问题,因为暂停按钮仍然可见,就好像它仍在播放音频一样。 请参阅图片进行说明:

我有一个不再在屏幕上播放音频的单元格。然后我点击第一个单元格上的播放。音频在第一个单元格停止并开始播放

现在我滚动到底部,虽然单元格不再播放,但暂停按钮仍然可见。我需要一种方法来调用单元格来更改该按钮的状态

【问题讨论】:

  • 请不要问“额外的问题”。将每个帖子保留在一个问题上。如果您有其他问题,请发布其他问题。
  • 如果单元格不可见,cellForRow(at:) 确实返回 nil。我要做的是只使用一个播放器(在 ViewController 中,一个单例?),编辑你的数组对象(你可以用 indexPath 检索)保持“isPlaying”,“currentProgression”(为了能够做一个“playAtTime”)等。
  • @Larme 我试过了,但它仍然给我留下了更新不可见单元格的问题。我用一些图片更新了我的问题以说明案例

标签: ios swift uitableview avplayer


【解决方案1】:

因此,修复了 2 个问题中的一个,即同时播放 2 个音频。现在是第二个问题,即刷新 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
}

【讨论】:

    猜你喜欢
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 2016-01-12
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 2014-07-15
    相关资源
    最近更新 更多