V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
marginleft
V2EX  ›  问与答

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

  •  
  •   marginleft · 2015-07-17 09:32:12 +08:00 · 3144 次点击
    这是一个创建于 3447 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如一个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中提到了上面的做法,很可惜并没有说明原因,所以询问一下大家的看法。

    5 条回复    2015-07-17 14:15:30 +08:00
    jianzong
        1
    jianzong  
       2015-07-17 10:36:11 +08:00 via iPhone
    简单说说我的看法:
    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
        2
    jianzong  
       2015-07-17 10:37:39 +08:00 via iPhone
    @jianzong Ps 现在项目中因为app不允许横屏或者各种尺寸变化,所以我为了简化(偷懒)也是在loadView里面放置constraint代码的。。。
    marginleft
        3
    marginleft  
    OP
       2015-07-17 13:28:07 +08:00
    @jianzong 感谢您的回复。我从您的文章「A Note On Using Auto Layout」中受益匪浅。
    66450146
        4
    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
        5
    jianzong  
       2015-07-17 14:15:30 +08:00
    @marginleft 很高兴对你有帮助。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4755 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 04:01 · PVG 12:01 · LAX 20:01 · JFK 23:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.