NSLayoutConstraint以编程方式设置视图框架

时间:2015-10-18 20:59:07

标签: ios objective-c autolayout

我知道有类似的主题,但我无法弄清楚如何做简单的事情,例如,使用自动布局约束以编程方式设置视图框。使用Storyboard很容易,但是当我尝试了解NSLayourConstraint时,我意识到我不理解主题。

考虑一下我们有UIView和3个按钮。顶部的第一个按钮有3个约束(前导和尾随,以及视图的顶部)。其他2个按钮与该按钮水平居中,宽度相等。它非常简单的布局,我上传截图:

enter image description here

我已经阅读过有关视觉格式语言的内容,但我无法理解的是 - 如何创建约束,例如,转发到顶部(或尾随领先)?如下: enter image description here

任务看起来很简单,但仍然没有找到一种方法如何使用NSLayoutConstraint以编程方式执行此操作。你能提供解决方案吗?感谢。

1 个答案:

答案 0 :(得分:1)

这是一个解决方案(应该进入-viewDidLoad)。有几点需要注意:

首先,VFL不允许您创建所有可能的约束类型。特别是,需要使用+constraintWithItem:上的NSLayoutConstraint类方法进行居中。

其次,如评论中所述,您可以在水平VFL字符串中使用硬编码的左右填充值来实现居中,但如果您需要支持不同的设备大小,这可能会导致问题。

第三,呼叫-setTranslatesAutoresizingMaskIntoConstraints:至关重要。如果忘记这一点,程序化Autolayout将完全失败。此外,您需要确保在设置约束之前将所有视图添加到其超级视图中,否则任何引用超级视图的约束字符串都将导致崩溃

NSArray *names = @[@"button1",@"button2",@"button3"];
NSMutableDictionary *views = [[NSMutableDictionary alloc]init];

for(NSUInteger i=0;i<3;i++) {
    UIButton *b = [[UIButton alloc]init];
    NSString *name = names[i];
    [b setTitle:name forState:UIControlStateNormal];
    views[name] = b;
    [b setBackgroundColor:[UIColor redColor]];
    [b setTranslatesAutoresizingMaskIntoConstraints:false];
    [self.view addSubview:b];
}
//List of values to be used in the constraints
NSDictionary *metrics = @{
  @"buttonWidth":@150,
  @"bHeight":@50, //button height
  @"topPad":@100,
  @"vPad":@20 //vertical padding
};

//Horizontal VFL string (repeated for all rows).

for (NSString *buttonName in views.allKeys) {
    NSString *horizontalConstraintString = [NSString stringWithFormat:@"|-(>=0)-[%@(buttonWidth)]-(>=0)-|",buttonName];
    NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:horizontalConstraintString options:0 metrics:metrics views:views];
    [self.view addConstraints:horizontalConstraints];
    //Can't do centering with VFL - have to use constructor instead. You could also hardcode left and right padding in the VFL string above, but this will make it harder to deal with different screen sizes
    NSLayoutConstraint *centerConstraint = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:views[buttonName] attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0];

    [self.view addConstraint:centerConstraint];
}

//Vertical VFL (vertical spacing of all buttons)

NSString *verticalConstraintString = @"V:|-topPad-[button1(bHeight)]-vPad-[button2(bHeight)]-vPad-[button3(bHeight)]-(>=0)-|";
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:verticalConstraintString options:0 metrics:metrics views:views];

[self.view addConstraints:verticalConstraints];
[self.view layoutIfNeeded];