hachinoBlog

hachinobuのエンジニアライフ

NSLayoutConstraintを使ってAutoLayoutをコードで書く

背景

AutoLayoutをxib上で使っているのだけれどxibでは表現できるAutoLayoutに限界があると思いコードで書く方法を調べたのでメモ。

サンプル

1.self.viewから左20,上20のマージンをとった位置にwidth100,height100の赤いViewを配置

    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    redView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:redView];
    NSLayoutConstraint *redLeftConstraint = [NSLayoutConstraint constraintWithItem:redView
                                                                         attribute:NSLayoutAttributeLeft
                                                                         relatedBy:NSLayoutRelationEqual
                                                                            toItem:self.view
                                                                         attribute:NSLayoutAttributeLeft
                                                                        multiplier:1
                                                                          constant:20];
    
    NSLayoutConstraint *redTopConstraint = [NSLayoutConstraint constraintWithItem:redView
                                                                     attribute:NSLayoutAttributeTop
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:self.topLayoutGuide
                                                                     attribute:NSLayoutAttributeTop
                                                                    multiplier:1
                                                                      constant:20];
    
    NSLayoutConstraint *redWidthConstraint = [NSLayoutConstraint constraintWithItem:redView
                                                                       attribute:NSLayoutAttributeWidth
                                                                       relatedBy:NSLayoutRelationEqual
                                                                          toItem:nil
                                                                       attribute:NSLayoutAttributeNotAnAttribute
                                                                      multiplier:1
                                                                        constant:100];
    
    NSLayoutConstraint *redHeightConstraint = [NSLayoutConstraint constraintWithItem:redView
                                                                        attribute:NSLayoutAttributeHeight
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:nil
                                                                        attribute:NSLayoutAttributeNotAnAttribute
                                                                       multiplier:1
                                                                         constant:100];
    
    [self.view addConstraints:@[redLeftConstraint, redTopConstraint, redWidthConstraint, redHeightConstraint]];

f:id:hachinobu:20141103191352p:plain

f:id:hachinobu:20141103191351p:plain

2.self.viewのbottom部分に幅=端末幅,高さ40の青いView配置

    UIView *blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    blueView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:blueView];
    NSLayoutConstraint *blueLeftConstraint = [NSLayoutConstraint constraintWithItem:blueView
                                                                             attribute:NSLayoutAttributeLeft
                                                                             relatedBy:NSLayoutRelationEqual
                                                                                toItem:self.view
                                                                             attribute:NSLayoutAttributeLeft
                                                                            multiplier:1
                                                                              constant:0];
    NSLayoutConstraint *blueRightConstraint = [NSLayoutConstraint constraintWithItem:blueView
                                                                              attribute:NSLayoutAttributeRight
                                                                              relatedBy:NSLayoutRelationEqual
                                                                                 toItem:self.view
                                                                              attribute:NSLayoutAttributeRight
                                                                             multiplier:1
                                                                               constant:0];
    NSLayoutConstraint *blueHeightConstraint = [NSLayoutConstraint constraintWithItem:blueView
                                                                            attribute:NSLayoutAttributeHeight
                                                                            relatedBy:NSLayoutRelationEqual
                                                                               toItem:nil
                                                                            attribute:NSLayoutAttributeNotAnAttribute
                                                                           multiplier:1
                                                                             constant:40];
    NSLayoutConstraint *blueTopConstraint = [NSLayoutConstraint constraintWithItem:blueView
                                                                        attribute:NSLayoutAttributeTop
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:self.view
                                                                        attribute:NSLayoutAttributeBottom
                                                                        multiplier:1
                                                                          constant:-blueHeightConstraint.constant];
    [self.view addConstraints:@[blueLeftConstraint, blueRightConstraint, blueTopConstraint, blueHeightConstraint]];

f:id:hachinobu:20141103202832p:plain

f:id:hachinobu:20141103202833p:plain

3.self.viewのcenter座標に幅=self.view.frame.width/2 高さ=self.view.frame.height/2 の黄色Viewを配置

    UIView *yellowView = [[UIView alloc] init];
    yellowView.backgroundColor = [UIColor yellowColor];
    yellowView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:yellowView];
    NSLayoutConstraint *yellowCenterXConstraint = [NSLayoutConstraint constraintWithItem:yellowView
                                                                            attribute:NSLayoutAttributeCenterX
                                                                            relatedBy:NSLayoutRelationEqual
                                                                               toItem:self.view
                                                                            attribute:NSLayoutAttributeCenterX
                                                                              multiplier:1
                                                                                constant:0];
    NSLayoutConstraint *yellowCenterYConstraint = [NSLayoutConstraint constraintWithItem:yellowView
                                                                               attribute:NSLayoutAttributeCenterY
                                                                               relatedBy:NSLayoutRelationEqual
                                                                                  toItem:self.view
                                                                               attribute:NSLayoutAttributeCenterY
                                                                              multiplier:1
                                                                                constant:0];
    NSLayoutConstraint *yellowWidthConstraint = [NSLayoutConstraint constraintWithItem:yellowView
                                                                             attribute:NSLayoutAttributeWidth
                                                                             relatedBy:NSLayoutRelationEqual
                                                                                toItem:self.view
                                                                             attribute:NSLayoutAttributeWidth
                                                                            multiplier:.5
                                                                              constant:0];
    NSLayoutConstraint *yellowHeightConstraint = [NSLayoutConstraint constraintWithItem:yellowView
                                                                              attribute:NSLayoutAttributeHeight
                                                                              relatedBy:NSLayoutRelationEqual
                                                                                 toItem:self.view
                                                                              attribute:NSLayoutAttributeHeight
                                                                             multiplier:.5
                                                                               constant:0];
    [self.view addConstraints:@[yellowCenterXConstraint, yellowCenterYConstraint, yellowWidthConstraint, yellowHeightConstraint]];

f:id:hachinobu:20141103203343p:plain

f:id:hachinobu:20141103203344p:plain

共通する部分としてViewのtranslatesAutoresizingMaskIntoConstraintsプロパティは必ずNOにすること。

これをしないとAutolayoutが適用されない。

Viewを作成する際にinitWithFrame:で幅と高さを指定しても意味はないのでNSLayoutConstraintのメソッドで幅と高さの制約を作る必要がある。

組み合わせや使い方によっては柔軟なものができそうであるが、それにしてもNSLayoutConstraintはマゾい

なので今度Masonryを試してみようと思う。