使用 Visual Format Language 定义水平和垂直约束
1.问题:
想要定义限制条件来改变一个 UI 组件在其父视图的水平和垂直方向布局的方法。
2.讨论:
使用 visual Format Language 在水平方向的限制条件使用的三个例子 :
H:|-100-[_button]-100-|
H:|-(<=100)-[_button(>=50)]-(<=100)-|
H:|-[_button(>=100,<=200)]
V:[_button]-(>=100)-|
(注意:为了让程序看起来整齐一致并使设计者更容易做出决定,Apple 已 经制定了 UI 之间的距离或留空标准。这个标准在 Apple 的 iOS Human Interface Guidelines 中进行了介绍。)
3.例子:
使用约束条件和Visual Format Language实现我们想要的UI
1)构造 UI 组件。所以我会写两个方法来帮助完成构造。记住,我们不需要再去设置这些 UI 组件的框架了。Auto Layout(自动布局)会帮助我们完成:
- (UITextField *)textFieldWithPlaceholder:(NSString *)paramPlaceholder{ UITextField *result = [[UITextField alloc]init]; result.translatesAutoresizingMaskIntoConstraints = NO; result.borderStyle = UITextBorderStyleRoundedRect; result.placeholder = paramPlaceholder; return result; } - (void)constructUIComponents{ _textFieldEmail = [self textFieldWithPlaceholder:@"Email"]; _textFieldConfirmEmail = [self textFieldWithPlaceholder:@"Confirm Email"]; _registerButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; _registerButton.translatesAutoresizingMaskIntoConstraints = NO; [_registerButton setTitle:@"Register" forState:UIControlStateNormal]; }
这个 textFieldWithPlaceHodler:方法仅仅创建了文本框,它包含一个指定的占位符文本, constructUIComponents 方法使用前面到的方法和按钮创建了两个文本框。
- (void)addUIComponentsToView:(UIView *)paramView{ [paramView addSubview:_textFieldEmail]; [paramView addSubview:_textFieldConfirmEmail]; [paramView addSubview:_registerButton]; }
这个方法来帮助我们将控件添加到指定View
2)
接下来的的任务就是创建一些方法,这些方法允许我们构造并收集所有的限制 条件到一个数组里。为此,我们有三个方法来返回每个 UI 组件的限制条件到一个数组里。 我们还有一个方法,它将收集从这三个 UI 组件返回的所有限制条件并将它们放进一个大的 数组里。下面是我们如何实现它的:
- (NSArray *)emailTextFieldConstraints{ NSMutableArray *result = [[NSMutableArray alloc]init]; NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_textFieldEmail); [result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_textFieldEmail]-|" options:0 metrics:nil views:viewsDictionary]]; //NSLayoutConstraint constraintsWithVisualFormat:<#(NSString *)#> options:<#(NSLayoutFormatOptions)#> metrics:<#(NSDictionary *)#> views:<#(NSDictionary *)#> [result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[_textFieldEmail]" options:0 metrics:nil views:viewsDictionary]]; return [NSArray arrayWithArray:result]; } - (NSArray *)confirmEmailTextFieldConstraints{ NSMutableArray *result = [[NSMutableArray alloc]init]; NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_textFieldConfirmEmail,_textFieldEmail); [result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_textFieldConfirmEmail]-|" options:0 metrics:nil views:viewsDictionary]]; [result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_textFieldEmail]-[_textFieldConfirmEmail]" options:0 metrics:nil views:viewsDictionary]]; return [NSArray arrayWithArray:result]; } - (NSArray *)registerButtonConstraints{ NSMutableArray *result = [[NSMutableArray alloc]init]; NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_registerButton,_textFieldConfirmEmail); [result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_textFieldConfirmEmail]-[_registerButton]" options:0 metrics:nil views:viewsDictionary]]; [result addObject:[NSLayoutConstraint constraintWithItem:_registerButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]]; return [NSArray arrayWithArray:result]; } //实际上这是视图控制器的限制条件实例方法,它将收集三个 UI 组件的所有限制条件并 将其返回到一个大的数组里。 - (NSArray *)constraints{ NSMutableArray *result = [[NSMutableArray alloc]init]; [result addObjectsFromArray:[self emailTextFieldConstraints]]; [result addObjectsFromArray:[self confirmEmailTextFieldConstraints]]; [result addObjectsFromArray:[self registerButtonConstraints]]; return [NSArray arrayWithArray:result]; }
实际上这是视图控制器的限制条件实例方法,它将收集三个 UI 组件的所有限制条件并 将其返回到一个大的数组里。现在到了控制器的主要部分了,就是这个 viewDidLoad 方法:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self constructUIComponents]; [self addUIComponentsToView:self.view]; [self.view addConstraints:[self constraints]]; } - (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskAll; }