iOS开发之NSLayoutConstraint

来源:互联网 发布:java中封装面试题 编辑:程序博客网 时间:2024/06/07 22:54

AutoLayout是从IOS 6开始苹果引入来取代autoresizing的新的布局技术。使用NSLayoutConstraint对view进行布局,就不需要计算view的frame。引入该约束API是为了更好的做一些屏幕适配的工作。

在使用NSLayoutConstraint之前需要知道以下两点:

  1. 必须设置 translatesAutoresizingMaskIntoConstraints为NO。
  2. 如果是viewControl则AutoLayout适配写在[- updateViewConstraints]中;如果是view则AutoLayout适配写在[- updateConstraints]中。
  3. NSLayoutConstraint是将约束添加到父控件中。

下面来简单的使用NSLayoutConstraint。首先创建两个view(redView, blueView)

- (void)viewDidLoad{    [super viewDidLoad];        // 红色view    UIView *redView = [[UIView alloc] init];    redView.backgroundColor = [UIColor redColor];    [self.view addSubview:redView];    self.redView = redView;    // 首先禁用UIViewAutoresizing    self.redView.translatesAutoresizingMaskIntoConstraints = NO;            // 蓝色view    UIView *blueView = [[UIView alloc] init];    blueView.backgroundColor = [UIColor blueColor];    [self.view addSubview:blueView];    self.blueView = blueView;    // 首先禁用UIViewAutoresizing    self.blueView.translatesAutoresizingMaskIntoConstraints = NO;}

下面只对redView相对于父控件self.view进行布局,确定redView的位置和尺寸方法很多,这里只是其中一种。

/** *  redView相对于父控件布局 */- (void)testConstraint1 {        // 开始对redView进行布局:NSLayoutConstraint    // NSLayoutConstraint使用公式:item.attribute = item.attribute * multi + constant    // redView的顶部约束    NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:self.view                                                                     attribute:NSLayoutAttributeTop                                                                     relatedBy:NSLayoutRelationEqual                                                                        toItem:self.redView                                                                     attribute:NSLayoutAttributeTop                                                                    multiplier:1.0                                                                      constant:-10];        // redView的左部约束    NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:self.view                                                                      attribute:NSLayoutAttributeLeft                                                                      relatedBy:NSLayoutRelationEqual                                                                         toItem:self.redView                                                                      attribute:NSLayoutAttributeLeft                                                                     multiplier:1.0                                                                       constant:-10];        // redView的高度约束    NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:self.view                                                                        attribute:NSLayoutAttributeHeight                                                                        relatedBy:NSLayoutRelationEqual                                                                           toItem:self.redView                                                                        attribute:NSLayoutAttributeHeight                                                                       multiplier:1.0                                                                         constant:100];        // redView的右部约束    NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:self.view                                                                       attribute:NSLayoutAttributeRight                                                                       relatedBy:NSLayoutRelationEqual                                                                          toItem:self.redView                                                                       attribute:NSLayoutAttributeRight                                                                      multiplier:1.0                                                                        constant:10];            // 设置redView的约束    [self.view addConstraints:@[topConstraint, leftConstraint, heightConstraint, rightConstraint]];}

横竖屏效果:


上面介绍的是子控件相对于父控件的布局,下面介绍两个子控件之间的相对约束,并设置redView高度约束的优先级。

/** *  blueView相对于redView进行布局 */- (void)testConstraint2 {        // 开始对redView进行布局:NSLayoutConstraint    // NSLayoutConstraint使用公式:item.attribute = item.attribute * multi + constant    // redView的顶部约束    NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:self.redView                                                                     attribute:NSLayoutAttributeTop                                                                     relatedBy:NSLayoutRelationEqual                                                                        toItem:self.view                                                                     attribute:NSLayoutAttributeTop                                                                    multiplier:1.0                                                                      constant:50];        // redView的左部约束    NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:self.redView                                                                      attribute:NSLayoutAttributeLeft                                                                      relatedBy:NSLayoutRelationEqual                                                                         toItem:self.view                                                                      attribute:NSLayoutAttributeLeft                                                                     multiplier:1.0                                                                       constant:50];        // redView的宽度约束    NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:self.redView                                                                       attribute:NSLayoutAttributeWidth                                                                       relatedBy:NSLayoutRelationEqual                                                                          toItem:self.view                                                                       attribute:NSLayoutAttributeWidth                                                                      multiplier:1.0                                                                        constant:-100];        // 设置高度最小200约束    NSLayoutConstraint *lessH = [NSLayoutConstraint constraintWithItem:self.redView                                                             attribute:NSLayoutAttributeHeight                                                             relatedBy:NSLayoutRelationGreaterThanOrEqual                                                                toItem:nil                                                             attribute:NSLayoutAttributeNotAnAttribute                                                            multiplier:1.0                                                              constant:200];            // 设置高度优先级    lessH.priority = UILayoutPriorityDefaultHigh;            // 设置redView的约束    [self.view addConstraints:@[topConstraint, leftConstraint, widthConstraint, lessH]];            // 开始对blueView进行布局:NSLayoutConstraint    // NSLayoutConstraint使用公式:item.attribute = item.attribute * multi + constant    // blueView的顶部约束    NSLayoutConstraint *bTopConstraint = [NSLayoutConstraint constraintWithItem:self.blueView                                                                      attribute:NSLayoutAttributeTop                                                                      relatedBy:NSLayoutRelationEqual                                                                         toItem:self.redView                                                                      attribute:NSLayoutAttributeBottom                                                                     multiplier:1.0                                                                       constant:50];        // blueView的左部约束    NSLayoutConstraint *bLeftConstraint = [NSLayoutConstraint constraintWithItem:self.blueView                                                                       attribute:NSLayoutAttributeLeft                                                                       relatedBy:NSLayoutRelationEqual                                                                          toItem:self.redView                                                                       attribute:NSLayoutAttributeLeft                                                                      multiplier:1.0                                                                        constant:0];        // blueView的宽度约束    NSLayoutConstraint *bWidthConstraint = [NSLayoutConstraint constraintWithItem:self.blueView                                                                        attribute:NSLayoutAttributeWidth                                                                        relatedBy:NSLayoutRelationEqual                                                                           toItem:self.redView                                                                        attribute:NSLayoutAttributeWidth                                                                       multiplier:1.0                                                                         constant:0];        // blueView的高度约束    NSLayoutConstraint *bHeightConstraint = [NSLayoutConstraint constraintWithItem:self.blueView                                                                         attribute:NSLayoutAttributeHeight                                                                         relatedBy:NSLayoutRelationEqual                                                                            toItem:nil                                                                         attribute:NSLayoutAttributeNotAnAttribute                                                                        multiplier:0.0                                                                          constant:100];            // 设置blueView的约束    [self.view addConstraints:@[bTopConstraint, bLeftConstraint, bWidthConstraint, bHeightConstraint]];}

横竖屏效果:


使用NSLayoutConstraint对控件布局减少了计算frame的麻烦,不过从上面的代码可以看出来,要对一个控件进行简单的约束代码量还是很大的,不过这也是没有办法。

我们如何在NSLayoutConstraint布局中设置控件的动画和frame的改变呢?

  1. 要平移某个控件
  2. 对某个控件进行缩放

平移:找到对应的约束条件,去改变它的常量constant,如下点击控制器view将redView向下平移

/** *  查找一个试图中制定的约束contraint * *  @param view     被查找的试图 *  @param constant 常量 */- (void)replaceView:(UIView *)view topConstraintWithConstant:(CGFloat)constant{    // 遍历view上的所有约束    for (NSLayoutConstraint *constraint in view.superview.constraints) {                // 符合条件的约束        if (constraint.firstItem == view            && constraint.firstAttribute == NSLayoutAttributeTop            ) {                        // 执行动画            [UIView animateWithDuration:2.0 animations:^{                                constraint.constant += constant;                [self.view layoutIfNeeded];// 重新布局            }];        }    }}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {        // 平移    [self replaceView:self.redView topConstraintWithConstant:200];    }
缩放:找到对应的约束条件,移除该约束条件,再添加一个新的约束条件

- (void)performAnimatView:(UIView *)view {    // 遍历view上的所有约束    for (NSLayoutConstraint *constraint in view.superview.constraints) {                // 符合条件的约束        if (constraint.firstItem == view            && constraint.firstAttribute == NSLayoutAttributeWidth            ) {                        // 移除该约束条件            [self.view removeConstraint:constraint];                                    // 添加新的约束条件,并执行动画            [UIView animateWithDuration:2.0 animations:^{                                NSLayoutConstraint *cw = [NSLayoutConstraint constraintWithItem:self.redView                                                                      attribute:NSLayoutAttributeWidth                                                                      relatedBy:NSLayoutRelationEqual                                                                         toItem:self.view                                                                      attribute:NSLayoutAttributeWidth                                                                     multiplier:1.0                                                                       constant:-200];                [self.view addConstraint:cw];                                [self.view layoutIfNeeded];// 重新布局            }];        }    }}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {        // 缩放    [self performAnimatView:self.redView];    }

注意:当修改一个view的约束的时候,其他相对于该view布局的视图都会跟着改变约束。

太累了。这些代码太繁琐了。

0 0
原创粉丝点击