美文网首页iOS开发实用技术
Auto Layout调试技巧集

Auto Layout调试技巧集

作者: kyson老师 | 来源:发表于2019-03-21 10:56 被阅读37次

    本系列博客是本人的开发笔记。为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui207407,【加我前请备注:iOS 】,本人博客http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

    iOS的Auto Layout布局给适配大小屏幕提供了一个比较好的解决方案,尤其是Masonry库的出现让Auto Layout布局页面更容易了。但由于Auto Layout高度的灵活性以及缺少相关Debug工具,使得使用Auto Layout很容易出现各种问题开发者却浑然不知,例如,我们经常在Xcode中看到如下日志:

    2013-07-23 17:36:08.920 FlexibleLayout[4237:907] 
    *<UIWindow:0x7269010>
    |   *<UILayoutContainerView:0x7381250>
    |   |   *<UITransitionView:0x737c4d0>
    |   |   |   *<UIViewControllerWrapperView:0x7271e20>
    |   |   |   |   *<UIView:0x7267c70>
    |   |   |   |   |   *<UIView:0x7270420> - AMBIGUOUS LAYOUT
    |   |   <UITabBar:0x726d440>
    |   |   |   <_UITabBarBackgroundView:0x7272530>
    |   |   |   <UITabBarButton:0x726e880>
    |   |   |   |   <UITabBarSwappableImageView:0x7270da0>
    |   |   |   |   <UITabBarButtonLabel:0x726dcb0>
    

    却又如从下手。当然,这只是Auto Layout的一种错误。常见的错误主要有以下几种:

    • 不满足条件的约束(Unsatisfiable Layouts)
    不满足条件的约束

    这种错误出现的主要原因是使用手动代码布局。

    • 模糊的约束(Ambiguous Layout)

    本文一开始提出的布局错误就属于模糊的约束问题,因为Auto Layout 非常灵活,出现Ambiguous Layout也不会报错,但其实大部分出现布局错误的问题都跟Ambiguous Layout有关。

    • 逻辑错误的约束(Logical Errors)

    这个很好理解,比如你设置了一个控件宽度为1000,超出了屏幕范围,那就属于这种错误。

    上面的三种问题是使用Auto Layout布局常见的问题。对于不同的情况大致的解决方案有一下几种:

    方法一:po命令

    常规的做法是在控制台输出该对象

    po (UIView *)(0x7270420)
    

    但打印的信息有限,基本不能定位到相应的View。

    方法二:条件断点

    设置 UIViewAlertForUnsatisfiableConstraints断点

    UIViewAlertForUnsatisfiableConstraints

    并在添加Action中添加po [[UIWindow keyWindow] _autolayoutTrace]

    image

    这种方式能较快的找出对应出现Auto Layout出错的View。但缺点也很明显,它会阻塞App执行直到我们把Auto Layout问题解决。如果我们项目中Auto Layout出问题的地方较少还能忍受,当出现的地方较多时不断卡住App运行的体验是让我们忍受不了的:团队开发中很多Auto Layout问题是分散在各处,有些并不是自己的Bug。

    方法二补充版本:chisel

    chisel是由Facebook开发的一款lldb插件,其提供了一些命令可以更快的帮我们定位问题,其主要的命令有:

    命令 描述
    pviews 递归打印所有的view,并能标示层级
    pvc 递归打印viewController层级
    visualize 可视化View

    方法三:使用AutoLayout提供的方法

    UIView有个标志是否存在Auto Layout错误(警告)的属性

    @property(nonatomic, readonly) BOOL hasAmbiguousLayout;
    
    

    这个属性见名知意:如果某个View存在布局模糊不清问题,这个属性就会返回YES,再配合方法

    - (void)exerciseAmbiguityInLayout ;
    

    即可提示开发者存在出现问题的AutoLayout布局。该方法会将存在问题的View以抖动的形式引起开发者注意。
    为了让布局问题更醒目的提示出来,我们可以给改View进行添加边框/着色等方式。下图是笔者公司项目中一个存在Ambiguous Layout问题的View,我给它添加了边框并将边框颜色设置成了红色:

    方法三

    这种方式的最大好处是,可以很友好的提示开发者出现问题的视图。为了方便大家使用,笔者将其开源供大家探讨:
    STFAutoLayoutDebugManager。这个工具还有一些欠缺的地方,比如只能提示ViewController中的View不能提示直接加到window中的View。

    方法四:给Constraint添加identifier

    Constraint有个分类可以标识Constraint:

    @interface NSLayoutConstraint (NSIdentifier)
    /* For ease in debugging, name a constraint by setting its identifier, which will be printed in the constraint's description.
     Identifiers starting with UI and NS are reserved by the system.
     */
    @property (copy) NSString *identifier NS_AVAILABLE_IOS(7_0);
    
    @end
    
    
    方法四

    或者通过代码设置:

    constraint.identifier = "$HeartImageFixedWidth$"
    

    添加了identifier后,原本的警告log是不是更好识别了:

    "<NSLayoutConstraint:0x7f92a305aeb0 '$ContainerStackViewLeading$' UIStackView:0x7f92a3053220.leading == UIView:0x7f92a3052fb0.leadingMargin + 32>",
    "<NSLayoutConstraint:0x7f92a305b340 '$ContainerStackViewTrailing$' UIView:0x7f92a3052fb0.trailingMargin == UIStackView:0x7f92a3053220.trailing + 32>",
    "<NSLayoutConstraint:0x7f92a301cf20 '$HeartImageFixedWidth$' H:[UIImageView:0x7f92a3047ef0(240)]>",
    "<NSLayoutConstraint:0x7f92a3009be0 '$StarImageFixedWidth$' H:[UIImageView:0x7f92a304d190(240)]>",
    "<NSLayoutConstraint:0x7f92a3060cc0 'UISV-alignment' UIStackView:0x7f92a30533b0.centerX == UIStackView:0x7f92a30472b0.centerX>",
    

    方法五:找到Will attempt to recover by breaking constraint这句话

    举例:有这么一句警告

    Will attempt to recover by breaking constraint 
    <MASLayoutConstraint:0x280a44780 UIButton:0x108bd4b60.height == 18>
    

    很显然,我们找到问题所在即是其height冲突,因此我们只需要设置Priority 即可:


    方法五

    总结

    Auto Layout问题在我们开发中因为没有强制性的报错而经常被忽视。笔者也是在发现公司App严重卡顿才开始关注Auto Layout相关问题。App的质量就是在各个模块的积累中慢慢提升的,希望大家对Auto Layout问题加以重视。

    参考

    Autolayout Breakpoints

    约束报错、冲突如何定位UI

    AutoLayout进阶

    Advanced Auto Layout Toolbox

    Debugging Auto Layout

    Using Identifiers to Debug Autolayout

    Unable to simultaneously satisfy constraints.错误处理

    相关文章

      网友评论

        本文标题:Auto Layout调试技巧集

        本文链接:https://www.haomeiwen.com/subject/xnxqvqtx.html