Objective c 正确处理代码中的NSLayoutConstraints

Objective c 正确处理代码中的NSLayoutConstraints,objective-c,autolayout,Objective C,Autolayout,我开始在我的最新项目中使用自动布局,我在某个点上被卡住了。我使用内容视图控制器,它将其他视图控制器添加为子视图控制器,并将它们的视图也添加为子视图。一切正常,只是我的子控制器视图的视图大小不正确 我的一个子视图控制器设置了一个类似滑块的东西,它有一个旋钮。此知识的初始位置取决于此视图的实际大小,这是不固定的,因为我以多种形式重用了它。一切都是用自动布局设置的。当然,因为此滑块的值来自代码的另一部分,所以“知道”的位置只能这样描述: self.knobVerticalPositionConstra

我开始在我的最新项目中使用自动布局,我在某个点上被卡住了。我使用内容视图控制器,它将其他视图控制器添加为子视图控制器,并将它们的视图也添加为子视图。一切正常,只是我的子控制器视图的视图大小不正确

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

self.knobVerticalPositionConstraint.constant = topPos + height * percentage;
其中,高度取决于滑块视图本身的大小

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

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

我读了整个互联网,但我没有找到这样的东西。它充满了关于“如何使用自动布局”的初学者和第一步指南,但我从未找到任何高级技巧


所以我的具体问题是:你们有什么最佳实践吗?如何组装一个视图控制器-视图对,它使用代码中的自动布局?在哪里设置约束?在哪里更新像我这样的约束常数,这取决于约束方程系统的计算值?哪些代码进入视图,哪些代码进入控制器?如果您能与我分享一些解决此问题的技巧,我将非常高兴。

我最近完成了我的第一个(也是目前为止唯一一个)iOS项目到自动布局的迁移。下面的内容大概是我从努力中得到的。虽然不多,但既然我想自己写下来,给你,也许会有帮助

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

  • 约束由设置视图层次结构的视图控制器或视图安装,因此了解并负责视图层次结构的布局。虽然这条规则非常基本,但有时记住它是值得的
  • UIView的
    translatesAutoResizezingMaskintoConstraints
    属性由为该UIView安装约束的视图控制器设置
  • 因此,视图控制器不会设置其自身根视图的
    translatesAutoresizingMaskIntoConstraints
    属性。相反,这是父视图控制器的责任
查看与iOS 7中的条处理相关的控制器属性:

  • edgesForExtendedLayout
    ,通常设置为
    UIRectEdgeNone
  • topLayoutGuide
    bottomLayoutGuide
  • 使所有条不透明(在iOS 7中,默认情况下所有条都是半透明的),这将允许属性
    extendedlayoutincludesopaquebar
    生效
还有一些陷阱:

  • 不要在
    ui窗口中安装约束。当我尝试这一点时,我遇到了麻烦,因为我解雇了一个风投,因为它是以模式呈现的
  • 视图控制器属性
    topLayoutGuide
    bottomLayoutGuide
    只能在视图控制器对
    ViewDidLayoutSubview
    的覆盖中使用,并且在它们用于安装约束后,必须调用
    [self.view LayoutSubview]
    。这个建议实际上来自苹果公司关于这两个属性的文档。不遵循建议可能会导致奇怪的布局问题(这发生在我身上)
  • 如果视图控制器的视图层次结构包含一个或多个滚动视图(例如表视图),并且存在意外的布局结果,则视图控制器属性
    automaticallyAdjustsScrollViewInsets
    可能正在发挥作用。将其设置为
    NO
    可能会有所帮助

顺便说一句,我个人最喜欢的用来理解自动布局的资源过去和现在都来自《编写iOS 6编程》一书。

你在调用视图上的-updateConstraints吗?我调用
self.progressWidth.constant=(1.0f-progress)*self.view.frame.size.width;[self.view layoutifneed]在动画块中更新我自己的进度视图(从左向右延伸的视图,而不是UIProgressView)时。如果您可以抓取其他约束(某些约束可能被覆盖)的屏幕截图,以及当前在代码中设置的位置,这可能会有所帮助。我的视图架构非常复杂:我有一个内容控件