正确处理代码中的NSLayoutConstraints

时间:2014-06-09 21:36:22

标签: objective-c autolayout

我在我的最新项目中开始使用AutoLayout,而且我在某些时候陷入困境。我使用内容视图控制器,它将其他视图控制器添加为子视图控制器,并将其视图添加为子视图。一切都很好,除了我的子控制器'视图有错误的视图大小。

我的一个子视图控制器设置了一个类似滑块的东西,它有一个旋钮。这种知识的初始位置取决于该视图的实际大小,这不是固定的,因为我以多种形式重用它。一切都是使用AutoLayout设置的。当然,因为这个滑块的值来自代码的另一部分,所以知道的位置只能这样描述:

self.knobVerticalPositionConstraint.constant = topPos + height * percentage;

其中height取决于滑块视图本身的大小。

问题是,当显示整个内容时,我的部分UI大小不正确。我甚至在子控制器-viewDidAppear中的视图大小错误。

我认为这是我编写代码的问题。也许不是一切都在它的位置。我读过这篇文章,它承诺以一种干净而优雅的方式来解决这类问题,但它从未透露过:

http://doing-it-wrong.mikeweller.com/2013/06/ios-app-architecture-and-tdd-1.html

我已阅读整个互联网,但我没有发现这样的事情。它充满了初学者的内容和关于"如何使用AutoLayout"的第一步指南,但我从未找到任何高级技巧。

所以我的具体问题是:您是否有任何最佳实践,如何组装使用代码中的AutoLayout的View Controller-View对?你在哪里设置你的约束?你在哪里更新像我这样的约束常量,这取决于约束平衡系统的计算值?什么代码进入View以及控制器的内容?如果你能分享一些解决这个问题的技巧,我很高兴。

1 个答案:

答案 0 :(得分:1)

我最近完成了将我的第一个(也是迄今为止)iOS项目迁移到Auto Layout。下面的内容大致是我从我的努力中汲取的东西。它并不多,但是因为无论如何我想把它写下来,你走了,也许它有所帮助。

  • 永不改变的静态约束进入视图控制器的loadView覆盖,或视图的初始化程序(或其某些子方法)
  • 依赖于布局系统计算的其他值的动态约束进入视图控制器的viewDidLayoutSubviews覆盖,或视图的layoutSubviews覆盖(在后一种情况下)首先调用[super layoutSubviews]来获取动态约束可以基于的更新值是有意义的。
  • 更改为动态约束后,可能需要告诉布局系统更改了某些内容。例如,在视图的layoutSubviews覆盖中,我在约束更改后第二次调用[super layoutSubviews],以便更新立即生效
  • 视图控制器也可以覆盖updateViewConstraints,视图可以覆盖updateConstraints,但到目前为止我还没有使用过它们。
  • 还有许多其他事件可能触发动态约束的更新(例如键盘事件),但这超出了最佳实践的范围。

一些一般性指导原则:

  • 约束由视图控制器或视图安装,后者设置视图层次结构,因此了解并负责视图层次结构的布局。虽然这个规则非常基本,但有时候要记住它。
  • UIView的translatesAutoresizingMaskIntoConstraints属性由该视图控制器设置,该控制器为该UIView安装约束
  • 因此,视图控制器设置其自己的根视图的translatesAutoresizingMaskIntoConstraints属性。相反,这是父视图控制器的责任。

在iOS 7中查看与条形处理相关的控制器属性:

  • edgesForExtendedLayout,通常设为UIRectEdgeNone
  • topLayoutGuidebottomLayoutGuide
  • 使所有条形图不透明(默认情况下,所有条形图在iOS 7中都是半透明的),然后允许属性extendedLayoutIncludesOpaqueBars启动

还有一些陷阱:

  • 不要在UIWindow中安装约束。当我尝试这种方法时,在以模态方式呈现VC后解雇VC时遇到了麻烦。
  • 视图控制器属性topLayoutGuidebottomLayoutGuide应仅在视图控制器覆盖viewDidLayoutSubviews内使用,在用于安装约束后,必须调用{ {1}}。这个建议实际上来自Apple对这两个属性的文档。不遵循建议可能会导致奇怪的布局问题(它发生在我身上)。
  • 如果视图控制器的视图层次结构包含一个或多个滚动视图(例如表视图),并且存在意外的布局结果,则视图控制器属性[self.view layoutSubviews]可能正在发挥作用。将其设置为automaticallyAdjustsScrollViewInsets可能会有所帮助。

顺便说一句,我个人最喜欢的资源来理解自动布局,现在仍然是this section来自书籍#34;编程iOS 6"。