tvOS 中是否有用于 Focus Engine 调试的隐藏工具?

Are there any hidden tools in tvOS for Focus Engine debugging?

我最喜欢的 iOS 隐藏调试工具之一是在 UIView 实例上使用 recursiveDescription。例如,这对于排除可能在屏幕外的视图位置的故障非常有用。在 tvOS 上调试 Focus Engine 会带来一系列挑战,尤其是围绕它认为可聚焦的元素。

tvOS 是否有任何隐藏的调试工具来检查 Focus 引擎内部发生的事情?

有两种有用的方法,它们实际上都记录在 App Programming Guide for tvOS

UIView

如果您尝试将焦点移动到特定视图但不能,UIView 上有一种调试方法可以帮助解释原因:_whyIsThisViewNotFocusable

此方法的输出如下所示:

(lldb) po [(UIView *)0x148db5234 _whyIsThisViewNotFocusable]
ISSUE: This view has userInteractionEnabled set to NO. Views must allow user interaction to be focusable.
ISSUE: This view returns NO from -canBecomeFocused.

UIFocusUpdateContext

UIFocusUpdateContext 对象支持 Xcode 的 QuickLook 功能,因此如果您在调试器中暂停,您可以按空格键(或单击变量旁边的眼球图标)来查看焦点引擎所见内容的图形表示(图片来自 Apple 的文档):

从 tvOS 11 开始,对无法访问的项目进行故障排除变得更加容易,只需将其添加到问题 ViewController 的 viewDidLoad 中:

 if #available(tvOS 11.0, *) {
  NotificationCenter.default.addObserver(
    forName: NSNotification.Name.UIFocusMovementDidFail
  ) { [weak self] notification in
    let context = notification.userInfo![UIFocusUpdateContextKey] as! UIFocusUpdateContext
    print(context) // If you add a breakpoint here you can quicklook the context in the debugger for more information
    print(UIFocusDebugger.checkFocusability(for: self!.collectionView)) // replace collectionView with the view you want to check
  }
}

这会导致调试输出如下:

<UIFocusUpdateContext: 0x6080000fe800: previouslyFocusedItem=<UIKeyboard 0x7fc597d75610>, nextFocusedItem=(null), focusHeading=Down>

The following issues were found that would prevent this item from being focusable:
- ISSUE: The item is being visually occluded by the following items:
<UIView 0x7fc597c3a9e0>