tvOS16及以上Apple TV崩溃:Focus item无parentFocusEnvironment
问题描述
在tvOS 16或更高版本中,Apple TV应用出现崩溃,报错信息如下:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Focus item <golplustv.TvPagerViewCell: 0x7fba3bab6460> does not provide a parentFocusEnvironment.'
terminating with uncaught exception of type NSException
CoreSimulator 857.14 - Device: Apple TV (2B02A89D-BCCD-42DB-A4E6-04BD8A09CE60) - Runtime: tvOS 16.1 (20K67) - DeviceType: Apple TV
此前版本运行正常,自定义TvPagerViewCell的didUpdateFocus方法代码如下,不确定是否与此相关:
public override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) { if (context.nextFocusedView == self) { if let viewController = context.nextFocusedView?.parentViewController as? MainViewController { viewController.pagerView.scrollToItem(at: index, animated: true) NotificationCenter.default.post(name: ConstantsHelper.pagerViewChanged, object: index) } } }
可能原因与修复方案
1. 焦点更新时同步执行UI操作
tvOS 16对焦点环境的校验更严格,直接在didUpdateFocus中调用scrollToItem会触发视图层级变化,破坏当前cell的焦点环境。需把滚动操作放到焦点动画协调器中执行,确保和焦点状态变化同步:
public override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) { super.didUpdateFocus(in: context, with: coordinator) // 必须调用super方法 guard context.nextFocusedView == self, let viewController = parentViewController as? MainViewController else { return } coordinator.addCoordinatedAnimations({ viewController.pagerView.scrollToItem(at: self.index, animated: true) }, completion: { NotificationCenter.default.post(name: ConstantsHelper.pagerViewChanged, object: self.index) }) }
2. 确保cell的父焦点环境有效
- 检查
pagerView(UICollectionView或同类容器)的数据源、代理设置是否正确,cell是否被正确复用并挂载到父视图层级 - 避免在cell初始化、布局阶段过早处理焦点相关逻辑,确保cell完全添加到视图控制器的视图树后再参与焦点交互
3. 简化父控制器获取逻辑
无需通过context.nextFocusedView重复获取,直接使用cell自身的parentViewController属性,减少可选链调用的潜在问题:
// 替换原获取逻辑 if let viewController = parentViewController as? MainViewController { // 执行后续操作 }
其他排查方向
- 检查是否在scrollView代理、视图布局方法中对cell做了非常规的层级修改
- 临时移除NotificationCenter的通知发送逻辑,确认是否是通知触发的其他视图变化导致焦点环境异常
- 升级到最新tvOS版本,验证是否是系统已知bug已被修复
内容的提问来源于stack exchange,提问作者user20459409

