AutoLayout VFL 笔记

visual format language (VFL)

Available Symbols

VFL uses a number of symbols to describe your layout:

  • | superview
  • - standard spacing (usually 8 points; value can be changed if it is the spacing to the edge of a superview)
  • == equal widths (can be omitted)
  • -20- non standard spacing (20 points)
  • <= less than or equal to
  • >= greater than or equal to
  • @250 priority of the constraint; can have any value between 0 and 1000
    250 - low priority
    750 - high priority
    1000 - required priority

Example Format String

H:|-[icon(==iconDate)]-20-[iconLabel(120@250)]-20@750-[iconDate(>=50)]-|
  • H: 表示水平方向
  • |-[icon 表示 icon的左边距跟父视图的左边距间隔是标准的间隔
  • ==iconDate 表示 iconDate的宽度等于iconDate的宽度
  • ]-20-[iconLabel 表示 icon的右边缘跟iconLabel的左边缘距离20.
  • [iconLabel(120@250)] 表示: iconLabel的宽度为120点,优先级为低。 如果跟其他约束有冲突,iconLabel的宽度可以不为120.
  • -20@750- 表示: iconLabel的右边缘跟iconDate的左边缘的距离为20点,优先级为高。
  • [iconDate(>=50)] 表示: iconDate的宽度大于或等于50.
  • -| 表示: iconDate的右边缘距离superview的右边缘为标准距离.

例子:

    UILabel *hint = [[UILabel alloc] init];
    hint.text = @"label";
    hint.backgroundColor = [UIColor grayColor];
    [self.view addSubview:hint];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button setTitle:@"button" forState:UIControlStateNormal];
    [self.view addSubview:button];

    //关闭 autoresizing
    hint.translatesAutoresizingMaskIntoConstraints = NO;
    NSMutableArray *tempConstraints = [[NSMutableArray alloc] init];
    [tempConstraints addObjectsFromArray:
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topLayoutGuide]-0-[hint(==50)]"
                                             options:0
                                             metrics:nil
                                               views:@{@"topLayoutGuide":self.topLayoutGuide,@"hint":hint}]];
    [tempConstraints addObjectsFromArray:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:[hint(==200)]"
                                             options:0
                                             metrics:nil
                                               views:NSDictionaryOfVariableBindings(hint)]];
    [self.view addConstraints:tempConstraints];

    //关闭 autoresizing
    button.translatesAutoresizingMaskIntoConstraints = NO;
    NSMutableArray *buttonConstraints = [[NSMutableArray alloc] init];
    [buttonConstraints addObjectsFromArray:
    //toplayoutGuide是一个标准线,代表着可以开始布局的视图顶部
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topLayoutGuide]-50-[button(==50)]"
                                             options:0
                                             metrics:0
                                               views:@{@"button":button,@"topLayoutGuide":self.topLayoutGuide}]];

    [buttonConstraints addObjectsFromArray:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:[button(==120)]"
                                             options:0
                                             metrics:0
                                               views:@{@"button":button}]];

    // visual format language 做不了水平居中,得额外添加约束代码
    [self.view addConstraint:
     [NSLayoutConstraint constraintWithItem:button
                                  attribute:NSLayoutAttributeCenterX
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:self.view
                                  attribute:NSLayoutAttributeCenterX
                                 multiplier:1.0
                                   constant:0]];

    [self.view addConstraints:buttonConstraints];

布局效果图:

AutoLayout VFL 笔记_第1张图片

NSLayoutFormatOptions

    UIButton *goBack = [UIButton buttonWithType:UIButtonTypeCustom];
    [goBack setTitle:@"后一页" forState:UIControlStateNormal];
    [self.view addSubview:goBack];

    UIButton *goForward = [UIButton buttonWithType:UIButtonTypeCustom];
    [goForward setTitle:@"前一页" forState:UIControlStateNormal];
    [self.view addSubview:goForward];

    UIButton *refresh = [UIButton buttonWithType:UIButtonTypeCustom];
    [refresh setTitle:@"刷新" forState:UIControlStateNormal];
    [self.view addSubview:refresh];

    goBack.translatesAutoresizingMaskIntoConstraints = NO;
    NSMutableArray *goBackConstraints = [[NSMutableArray alloc] init];
    [goBackConstraints addObjectsFromArray:
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:[goBack(30)]-20-[bottomLayoutGuide]"
                                             options:0
                                             metrics:nil
                                               views:@{@"goBack":goBack,@"bottomLayoutGuide":self.bottomLayoutGuide}]];
    [goBackConstraints addObjectsFromArray:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[goBack(60)]"
                                             options:0
                                             metrics:nil
                                               views:@{@"goBack":goBack}]];

    goForward.translatesAutoresizingMaskIntoConstraints = NO;
    [goBackConstraints addObjectsFromArray:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:[goBack]-30-[goForward(60)]"
                                             options:NSLayoutFormatAlignAllCenterY
                                             metrics:nil
                                               views:NSDictionaryOfVariableBindings(goBack,goForward)]];

    refresh.translatesAutoresizingMaskIntoConstraints = NO;
    [goBackConstraints addObjectsFromArray:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:[goForward]-30@250-[refresh]-50@750-|"
                                             options:NSLayoutFormatAlignAllCenterY
                                             metrics:nil
                                               views:NSDictionaryOfVariableBindings(goForward,refresh)]];

    [self.view addConstraints:goBackConstraints];

NSLayoutFormatAlignAllCenterY 表示跟其中一个关联的控件的 centerY的值一样(在VFL表达式中的元素,必须有一个的centerY值是确定的,这样才能确定其他元素的centerY的值)。 效果图如下:

AutoLayout VFL 笔记_第2张图片

其他值类推,例如有这样的:

     constraintsWithVisualFormat:@"V:[Label1]-4-[Label2]",
      //使得 Label1的左右边缘等于Label2的左右边缘。
      options: [.alignAllLeading, .alignAllTrailing],
      metrics: nil,
      views: views]

     前提是:label2的左右边缘都已经确定了,上面的VFL约束才能正确执行
     @"H:|-15-[Label2]-15-|"

Metrics

Metrics其实就是定义 一些常量,或者变量。把常量名或者变量名应用到 VFL中。解析的时候,替换为相应的值。 例如:

[swift]
// MARK: - Constants
private let horizontalPadding: CGFloat = 15.0
let metrics = ["hp": horizontalPadding,
  "iconImageViewWidth": 30.0]

let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(
  "H:|-hp-[iconImageView(iconImageViewWidth)]-[appNameLabel]-[skipButton]-hp-|",
  options: [.AlignAllCenterY],
  metrics: metrics,
  views: views)

let summaryHorizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(
  "H:|-hp-[summaryLabel]-hp-|",
  options: [],
  metrics: metrics,
  views: views)

你可能感兴趣的:(AutoLayout VFL 笔记)