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

tvOS 16下UITableView调用reloadData崩溃:UITableViewCell无parentFocusEnvironment

问题概述

自Xcode 14(AppleTV SDK 16.0)及tvOS 16.0起,AppleTV应用在用户选中UITableViewCell后调用reloadData()更新表格时会崩溃,崩溃日志如下:

*** Assertion failure in -[_UIFocusItemInfo _createFocusedRegion], _UIFocusItemInfo.m:187
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Focus item <UITableViewCell: 0x7f92d202fc00> does not provide a parentFocusEnvironment.'

应用使用原生UITableViewCell,未重写parentFocusEnvironment属性,该属性缺失原因不明。

不同环境下的表现:

  • tvOS 15.4环境:无论使用Xcode 13.4.1还是14,应用均正常运行,无警告或日志;
  • tvOS 16.0环境+Xcode 13.4.1(AppleTV SDK 15.0):应用不崩溃,但选中单元格的失焦视图会留存于视图层级,系统日志提示该问题未来会引发崩溃:
[Assert] Focus item <UITableViewCell: 0x7fe4290a7c00> does not provide a parentFocusEnvironment.  This will become an assert in a future version.
[Assert] Failed to create FocusRegion for FocusItem: <UITableViewCell: 0x7ff129856600; frame = (0 800; 880 66); text = 'Show empty sections'; autoresize = W; layer = <CALayer: 0x600003a1f740>> with parentFocusEnvironment: (null)  focusItemContainer: (null)

已创建可复现该崩溃的示例项目,且已向苹果提交反馈暂未收到回复。

解决方案建议

以下是针对该焦点崩溃问题的可行修复/规避方案:

1. 刷新前主动移除单元格焦点

在调用reloadData()前,先让表格更新焦点状态,避免选中的单元格在刷新时仍持有焦点:

// 触发焦点更新,让选中单元格失焦
tableView.setNeedsFocusUpdate()
tableView.updateFocusIfNeeded()
// 或直接将焦点转移到导航栏等父容器
navigationController?.view.becomeFirstResponder()
// 执行刷新
tableView.reloadData()

2. 使用局部刷新替代全局reloadData()

避免全量刷新表格,仅刷新需要更新的行或section,减少视图层级重建带来的焦点问题:

// 刷新指定section
tableView.reloadSections(IndexSet(integer: targetSection), with: .automatic)
// 刷新指定行
tableView.reloadRows(at: [targetIndexPath], with: .automatic)

3. 临时修复parentFocusEnvironment(Workaround)

通过分类强制让单元格返回有效的parentFocusEnvironment,绕过苹果的断言检查(仅作为临时方案,待苹果官方修复后建议移除):

extension UITableViewCell {
    override open var parentFocusEnvironment: UIFocusEnvironment? {
        return super.parentFocusEnvironment ?? self.superview
    }
}

4. 延迟刷新等待焦点状态稳定

在单元格选中事件后延迟一小段时间再执行刷新,让系统完成焦点状态的清理:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    self.tableView.reloadData()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 20:11:09