You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测TableView焦点单元格并控制视频播放与暂停

解决TableView焦点单元格视频单独播放的问题

我来帮你搞定这个多视频同步播放的问题,核心是要精准跟踪焦点单元格,确保只有它的视频在播放,其他单元格的视频都暂停。你的现有代码在didEndDisplaying里的cell获取逻辑有问题,下面是完整的修复方案:

1. 先在ViewController里添加焦点跟踪变量

首先我们需要保存当前焦点单元格的indexPath,方便后续切换状态时使用:

class MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    private var focusedIndexPath: IndexPath?
    // 你的其他属性和代码...
}

2. 修正didEndDisplaying方法

你原来的代码里用tableView.cellForRow(at: indexPath)是错误的——当cell离开屏幕时,这个方法大概率返回nil,因为cell已经被移出可视区域甚至被复用了。直接用方法参数里的cell即可:

func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if let listCell = cell as? ListViewCell {
        listCell.player?.pause()
        // 可选:如果需要节省资源,可以在这里重置player
        // listCell.player?.seek(to: .zero)
    }
}

3. 处理焦点变化事件(tvOS场景)

因为你提到了“焦点单元格”,推测是tvOS开发。我们需要在焦点切换时,暂停之前焦点单元格的视频,播放当前焦点单元格的视频:

override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
    super.didUpdateFocus(in: context, with: coordinator)
    
    // 暂停之前焦点单元格的视频
    if let previousIndexPath = focusedIndexPath, let cell = tableView.cellForRow(at: previousIndexPath) as? ListViewCell {
        cell.player?.pause()
    }
    
    // 获取当前焦点单元格的indexPath
    if let nextFocusedView = context.nextFocusedView {
        var currentCell: ListViewCell?
        // 处理焦点视图是cell子视图的情况
        if let cell = nextFocusedView as? ListViewCell {
            currentCell = cell
        } else if let cell = nextFocusedView.superview as? ListViewCell {
            currentCell = cell
        }
        
        if let cell = currentCell {
            focusedIndexPath = tableView.indexPath(for: cell)
            cell.player?.play()
        }
    }
}

4. 给Cell添加复用重置逻辑

当cell被复用时,一定要暂停之前的视频,避免复用后视频继续播放:

class ListViewCell: UITableViewCell {
    var player: AVPlayer?
    
    override func prepareForReuse() {
        super.prepareForReuse()
        player?.pause()
        player?.seek(to: .zero) // 重置到视频开头
    }
    
    // 你的cell其他代码...
}

5. 在cellForRowAt里初始化播放状态

加载cell时,判断当前cell是否是焦点单元格,对应设置播放/暂停状态:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ListViewCell", for: indexPath) as! ListViewCell
    
    // 这里配置你的player,比如设置视频URL
    // let videoURL = yourVideoURLs[indexPath.row]
    // cell.player = AVPlayer(url: videoURL)
    
    // 根据焦点状态设置播放状态
    if indexPath == focusedIndexPath {
        cell.player?.play()
    } else {
        cell.player?.pause()
    }
    
    return cell
}

这样一套流程下来,就能保证只有当前焦点单元格的视频在播放,其他单元格的视频都会被暂停,完美解决同步播放的问题~

内容的提问来源于stack exchange,提问作者Kerim Khasbulatov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:20:04