添加 NSLayoutConstraints 的代码放在什么位置?

2015-07-17 09:32:12 +08:00
 marginleft

比如一个UIViewController中。今天看到PureLayout中看到是这样组织的:

  1. 在loadView 中初始化UIView并添加,最后调用setNeedsUpdateConstraints
  2. 在updateViewConstraints中设置NSLayoutConstraints,并在最后调用[super updateViewConstraints],另外,为了不重复调用,用到了BOOL didSetupConstraints。
- (void)loadView
{
    self.view = [UIView new];

    [self.view addSubview:self.blueView];
    [self.view addSubview:self.redView];
    [self.view addSubview:self.yellowView];
    [self.view addSubview:self.greenView];

    [self.view setNeedsUpdateConstraints]; // bootstrap Auto Layout
}

- (void)updateViewConstraints
{
    if (!self.didSetupConstraints) {
        // Apply a fixed height of 50 pt to two views at once, and a fixed height of 70 pt to another two views
        [@[self.redView, self.yellowView] autoSetViewsDimension:ALDimensionHeight toSize:50.0];
        [@[self.blueView, self.greenView] autoSetViewsDimension:ALDimensionHeight toSize:70.0];

        self.didSetupConstraints = YES;
    }

    [super updateViewConstraints];
}

问题来了:
1. 如果我在loadView中添加Constraints,这样肯定是添加一次的,也省得用didSetupConstraints了,不是更好吗?这样会有什么问题吗?
2. [super updateViewConstraints];为什么放到了updateViewConstraints的最后面,放在最前面会有什么问题呢?

PS: 在PureLayout的 Tips-and-Tricks中提到了上面的做法,很可惜并没有说明原因,所以询问一下大家的看法。

3028 次点击
所在节点    问与答
5 条回复
jianzong
2015-07-17 10:36:11 +08:00
简单说说我的看法:
1 在loadView中确实是只会添加一次,但是当这个view的subview调用updateViewConstraints的时候就不能更新constraint了。
2 因为update constraints的过程是bottom-up的,就是说parent view先update完成,child view再进行update,所以要把[super updateViewConstrsints]放最面。

前两天刚在stackoverflow回答过类似问题,供你参考 http://stackoverflow.com/questions/31400258/autolayout-updateconstraints-doest-not-get-call-on-orientation-change/31400876#31400876
jianzong
2015-07-17 10:37:39 +08:00
@jianzong Ps 现在项目中因为app不允许横屏或者各种尺寸变化,所以我为了简化(偷懒)也是在loadView里面放置constraint代码的。。。
marginleft
2015-07-17 13:28:07 +08:00
@jianzong 感谢您的回复。我从您的文章「A Note On Using Auto Layout」中受益匪浅。
66450146
2015-07-17 13:34:53 +08:00
1. 在 loadView 中添加 constraint 并把每个 size class 对应的 constraints 放到一个数组里面

比如 Compact Width | Regular Height 的放到一个数组里面,对应 iPhone 竖屏的 constraints,然后 Regular Width | Regular Height 的放到数组里面,以此类推

2. (iOS 8+ only) 在 - (void) willTransitionToTraitCollection 中用 [NSLayoutConstraint activateConstraints:] 和 [NSLayoutConstraint deactivateConstraints:],详情请看文档……
jianzong
2015-07-17 14:15:30 +08:00
@marginleft 很高兴对你有帮助。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/206296

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX