从 table 视图控制器引用特定的 table 视图单元格

Referencing a particular table view cell from table view controller

我有一个 UITableView,其中包含显示音频波形图像和播放按钮的单元格。当然,点击按钮会导致播放音频。为了减少内存使用,我在 table 视图控制器中声明了一个 AVAudioPlayer 实例。我定义了一个具有 playAudio(url:URL)stopPlayingAudio() 方法的协议,我的 table 视图控制器符合该协议。每当新单元格出列时,我都会将 table 视图控制器指定为单元格的委托,这样当用户点击单元格 UI 中的播放按钮时,它会调用 playAudio(url)委托方法。这似乎工作得很好,但我现在 运行 遇到了问题。

我正在计算音频播放时的完整百分比值,我想用这个值更新 table 视图单元格 UI,但我不确定如何引用来自 table 视图控制器的正确单元格。似乎被点击以开始音频播放的单元格如果滚动到屏幕外可能最终会被回收(除非我误解了单元格是如何动态出队的)。有办法吗?

如果您知道要查找 table 的哪一行,可以向 table 视图询问相应的单元格:

guard let cell = tableView.cellForRow(at: indexPath) as? WaveformCell {
    cell.fractionComplete = ...
}

有几种方法可以实现您想要实现的目标,

  1. 如果您正在维护一个数据源以创建一个单元格(如果不是,您应该从中创建),请维护单元格的状态,这可以包括单元格的播放百分比 url 和项目是否 isPlaying 的状态,默认情况下为 false。

  2. 状态就位后,您现在需要更新此状态,因此您必须添加创建协议(例如 AudioStateObserverProtocol)以将此数据发送到单元格,该协议可能有一种方法,可以在玩家玩游戏时定期更新单元格 UI(类似于 updatePlayDuration: 或类似的东西),这将确保您获得多少资产已播放。因此,当用户点击播放按钮而不是调用 playAudio(url:URL) 时,您可以将协议方法更新为 playAudio(url:URL, stateObserver: TheTableViewCell),table 视图控制器将其设置为 [=12= 类型的委托].

    protocol AudioStateObserverProtocol {
        func updatePlayDuration(to time: CMTime)
    }
    
  3. 将另一个协议方法 stopObserving(cell: TheTableViewCell) 添加到您使用 playAudio(url:URL)stopPlayingAudio()

  4. 定义的协议中
  5. 下一步是如何确保重复使用的单元格不会 receive/use 更新,要做到这一点,您可以确保在 cellForRow 你首先调用的数据源方法stopObserving(cell: TheTableViewCell)。在 table 视图控制器中执行此方法时,根据 AudioStateObserverProtocol 类型的参数检查单元格的实例,如果相同,则将其设置为 nil,以便该单元格不会再次获得更新.

  6. 这里要记住的一件重要事情是,如果您的音频仍在播放,那么您需要确保在创建该索引的单元格时显示更新,这是您将检查数据源的 isPlaying 状态,如果为真,则将单元格设置为 AudioStateObserverProtocol

  7. 类型的观察者