如何检查 iOS 中的视图层次结构?

Posted

技术标签:

【中文标题】如何检查 iOS 中的视图层次结构?【英文标题】:How do I inspect the view hierarchy in iOS? 【发布时间】:2011-07-06 05:32:36 【问题描述】:

是否有用于检查 ios 应用程序的视图层次结构的 GUI 工具?我正在考虑 Webkit 的网络检查器或类似工具。我正在寻找调试布局问题,例如位置或大小错误的视图,或者没有正确包含在其父级中的子级。目前我必须添加断言来手动测试这些不同的条件,或者在不同的视图上设置不同的背景颜色,你可以想象,这是一种非常乏味的方法。

我查看了 Instruments 的 UI recorder,但它只记录和播放 UI 动作`,而且无论如何,它只适用于 Mac 应用程序。

有没有更好的解决方案?

【问题讨论】:

【参考方案1】:

不知道有没有GUI视图检查工具,但是我在UIView上的调试方法有点运气:-recursiveDescription

如果您在调试器中暂停程序并将其输入 GDB(编辑:也适用于 LLDB)

po [[UIWindow keyWindow] recursiveDescription]

您将获得整个视图层次结构的打印输出。您还可以在特定视图上调用它以获取该视图的视图层次结构的打印输出。

浏览从中获得的信息可能有点乏味,但事实证明它对我很有用。

感谢this blog post,它谈到了这种方法,并链接到this helpful, but rather hard to find Apple tech note。

【讨论】:

我有:错误:找不到“$__lldb_objc_class”的接口声明有什么想法吗? (lldb) po [[UIWindow keyWindow] recursiveDescription] 错误:找不到“$__lldb_objc_class”的接口声明错误:找不到“$__lldb_objc_class”的接口声明错误:解析表达式时出现 2 个错误 我相信这个答案不再是标准答案,因为现在有可用的 GUI 工具可以直接回答“是否有 GUI 工具...?”的问题 从 xcode 5.1 开始,每当我输入 recursiveDescription 错误时,我就开始收到此错误:实例方法“undoManager”在不同的翻译单元中具有不兼容的结果类型(“id”与“NSUndoManager *”)注意:实例方法 'undoManager' 也在这里声明错误:1 解析表达式错误 虽然问题很老,并且询问图形方法,但这个具体答案与文本解决方案有关。可以找到关于规范代码内解决方案的讨论,例如这里:***.com/a/14193682/2431627。即通过 KVC 使用 _printHierarchy 属性。【参考方案2】:

Xcode 6 现在像 Reveal App 和 Spark Inspector 一样内置了 3D 视图层次结构检查。

在您的应用运行时单击“Debug View Hierarchy”按钮以暂停执行并检查当前的视图。

更多信息请访问Apple's documentation。

【讨论】:

如果视图调试选项不可用,请参阅***.com/questions/24040322/…。 起初,我没有看到 Levi McCallum 显示的工具栏,因为如果应用程序没有任何调试输出,它位于 Xcode 窗口的最底部。按下按钮后,View Hierarchy 窗口是空白的,直到我按下底部的一个按钮,或者调整了一个滑块。 一旦你开始依赖这个工具,它总是会失败。我不知道为什么或如何解决它,但它似乎发生在更复杂的视图上。【参考方案3】:

奇怪的是,现在还有另一种选择,http://revealapp.com/,截至本文发布时,它处于开放(免费)测试版中。如您所见,它是另一个视觉检查器。

编辑 2014-04-05:Reveal 已结束 Beta 版,不再免费。但是,有 30 天的试用期。

【讨论】:

我已经为此尝试了一些工具(Spark Inspector、iOS Hierarchy Viewer 和 Frank 测试工具中的类似萤火虫的视图)。到目前为止,Reveal 是我的最爱。 但完全还是值得的。比用于查看视图的内置 Xcode 工具要好得多【参考方案4】:

这个问题很老,但让我在这里放一下关于我开发的新工具的信息: https://github.com/glock45/iOS-Hierarchy-Viewer

【讨论】:

当我导航到模拟器中的另一个视图时,是否可以自动刷新页面?此外,是否可以更改此查看器中的值(因此我可以在浏览器上进行一些测试而无需编写真正的代码)?谢谢:) @Brian 感谢 Brain。我开始对改变价值观的可能性进行原型设计。它在正式版本中关闭。敬请期待! 非常感谢您的建议。我设法用这个工具解决了我的问题,一个使用 Xcode 的 UI 调试器无法解决的问题! 谢谢,达米安,但对于阅读本文的人来说,这个工具似乎无人维护。【参考方案5】:

为了让这个帖子保持最新,我最近一直在玩Spark Inspector。它不是免费的,但非常好。

【讨论】:

【参考方案6】:

FLEX Debugger 提供了一个应用内视图检查器,允许您在正在运行的应用中修改 UI。它还记录网络请求。

https://github.com/Flipboard/FLEX

【讨论】:

【参考方案7】:

免费:只需在检查器中输入:

po [[UIWindow keyWindow] recursiveDescription]

商业:http://revealapp.com/我测试了revealapp的beta版本,虽然有错误,但很好。 另一个商业工具:http://sparkinspector.com/ 无缝运行。

【讨论】:

Spark Inspector 有一个不错的通知查看器【参考方案8】:

斯威夫特 4.

iOS

extension UIView 

   // Prints results of internal Apple API method `recursiveDescription` to console.
   public func dump() 
      Swift.print(perform(Selector(("recursiveDescription"))))
   

ma​​cOS

extension NSView 

   // Prints results of internal Apple API method `_subtreeDescription` to console.
   public func dump() 
      Swift.print(perform(Selector(("_subtreeDescription"))))
   

用法(在调试器中):po myView.dump()

【讨论】:

【参考方案9】:

这会在调试窗口中转储所有内容。(很难阅读):( 在 iOS 10、Xcode 8.3.3 上工作

po UIApplication.shared.keyWindow?.recursiveDescription()

【讨论】:

【参考方案10】:

使用 Xcode 8 和 Swift 2.3,已批准的答案不再适用于我。以下是对我有用的方法:

po UIApplication.sharedApplication().keyWindow?.recursiveDescription()

【讨论】:

谢谢,mph,但这在 Swift 3 中也不起作用:错误:在“UIApplication”类型的对象上找不到属性“shared” Swift 4 和 Xcode 9.1 抱怨“错误::3:32: 错误:无法调用非函数类型 'UIApplication' UIApplication.sharedApplication().keyWindow?.recursiveDescription( )"【参考方案11】:

对于 swift/Xcode 10,在调试控制台中输入:

po yourView.value(forKey: "recursiveDescription")!

它将打印出任何给定UIView的递归层次结构。

(信用:How to debug your view hierarchy using recursiveDescription)

【讨论】:

以上是关于如何检查 iOS 中的视图层次结构?的主要内容,如果未能解决你的问题,请参考以下文章

如何以模态方式将视图添加到不在视图层次结构中的另一个视图 iOS

如何解决此错误“警告:尝试呈现其视图不在窗口层次结构中”?

iOS viewWillAppear 错误:“视图不在窗口层次结构中”

iOS 视图与视图层次结构(内容根据iOS编程)

视图层次结构未准备好

如何修复 AVPlayer 的视图控制器层次结构?