【iOS开发】---- iOS自动布局(二)
来源:互联网 发布:喷绘图设计软件 编辑:程序博客网 时间:2024/06/03 11:47
上一篇文章提到了苹果已经创建了Visual Format language(可视化格式语言),可以用来实现自动布局。
如果有两个按钮你想将它们在水平方向相隔100 像素,你可以使用Visual Format language 代码来表达,如下:
[button1]-100-[button2]Visual Format Language 中的限制条件是通过NSLayoutConstraint 类中的constrainsWithVisualFormat:ptions:metrics:views:的类方法。下面简单解释一下方法中每个参数:
constraintsWithVisualFormat
这是Visual Format Language 的表达式,被写成了NSString。
Options
这是一个NSLayoutFormatOption 类型的参数。对于Visual Format Language,我们通常将这个参数设置为0。
Metrics
一个字典常量值,将会在Visual Format Language 表达式中使用到。为了简单一点,目前我们将会传入nil 值。
Views
这是一个视图字典,你将会在这个方法的第一个参数写限制条件。为了构造这个字典,简单地使用NSDIctionaryOfVaribleBindings C 函数并传递你的视图到这个方法里。它将会为你构造这个字典。在这个字典的关键字是视图的名字,你将会在方法的第一个参数中使用它。
问题
想要定义限制条件来改变一个UI 组件在其父视图的水平和垂直方向布局的方法。
方案
使用方程式里H:方向符号代表水平方向的边距,使用V:方向符号代表垂直方向的边距。
使用方程式里H:方向符号代表水平方向的边距,使用V:方向符号代表垂直方向的边距。
下面有一张图,它能够帮助我们很好地理解Visual Format Language。
为了让程序看起来整齐一致并使设计者更容易做出决定,Apple 已经制定了UI 之间的距离或留空标准。这个标准在Apple 的iOS Human Interface Guidelines 中进行了介绍。
现在我们将要用Visual Format Language来实现下图的布局。
在编辑代码之前,让我们先写一下在图中组件的约束条件:
·邮件区域离视图的顶部具有一个标准的垂直方向距离。
·确认邮件的区域在垂直方向山距邮件区域有一个标准的距离。
·注册按钮距确认邮件区域的垂直方向上具有一个标准的距离。
·所有的组件在水平方向上在其父视图中都是居中的。
·邮件和确认邮件区域在水平方向上距父视图两边都有一个标准的距离。
·按钮的宽度被修改成128 像素。
·邮件区域离视图的顶部具有一个标准的垂直方向距离。
·确认邮件的区域在垂直方向山距邮件区域有一个标准的距离。
·注册按钮距确认邮件区域的垂直方向上具有一个标准的距离。
·所有的组件在水平方向上在其父视图中都是居中的。
·邮件和确认邮件区域在水平方向上距父视图两边都有一个标准的距离。
·按钮的宽度被修改成128 像素。
让我们先从使用Visual Format Language 在视图控制器顶部定义约束条件开始吧:
/*Email text Field constraints*/NSString *const KEmailTextFieldHorizontal = @"H:|-[_textFieldEmail]-|";NSString *const KEmailTextFieldVertical = @"V:|-[_textFieldEmail]";/*Confirm email text field constraints */NSString *const KConfirmEmailHorizontal = @"H:|-[_textFieldConfirmEmail]-|";NSString *const KConfirmEmailVertical = @"V:[_textFieldEmail]-[_textFieldConfirmEmail]";/*Redister button constraint */NSString *const KRegisterVertical = @"V:[_textFieldConfirmEmail]-[_registerButton]";
很显然两个文本框都有它们自己的水平和垂直方向的Visual Format Language 定义的限制条件,但是Register 按钮只有在垂直方向的限制条件。为什么呢?结果表明UI 组件在水平方向的居中条件不能由Visual Format Language 定义.任何东西都不是完美的,在上一篇自动布局的文章我们已经学会了如何自动布局按钮的水平约束条件了(忘了的复习一下吧)。
现在让我们在视图控制器的执行文件将我么的UI 组件定义成我们视图控制器的私有属性:
@interface ViewController ()@property(nonatomic,strong) UIButton *button;@property (nonatomic,strong)UITextField *textFieldEmail;@property (nonatomic,strong)UITextField *textFieldConfirmEmail;@property (nonatomic,strong)UIButton *registerButton;@end
接下来呢?我们需要在视图控制器的执行文件里构造我们的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{ self.textFieldEmail = [self textFieldWithPlaceholder:@"Email"]; self.textFieldConfirmEmail =[self textFieldWithPlaceholder:@"Confirm Email"]; self.registerButton = [UIButton buttonWithType:UIButtonTypeCustom]; [self.registerButton setBackgroundColor:[UIColor blackColor]]; self.registerButton.translatesAutoresizingMaskIntoConstraints = NO; [self.registerButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [self.registerButton setTitle:@"Register" forState:UIControlStateNormal];}
上面的两个方法创建了两个文本框和一个按钮。其中translatesAutoresizingMaskIntoConstraints这个属性在上一篇文章中有解释。
我们将构造UI 组件了,但是我们的视图控制器的viewDidLoad 方法需要将这三个UI 组件都添加到我们的视图中,所以问什么不使用一个简短的方法来帮助我们完成呢?
- (void) addUIComponentsToView:(UIView *)paramView{ [paramView addSubview:self.textFieldEmail]; [paramView addSubview:self.textFieldConfirmEmail]; [paramView addSubview:self.registerButton];}
在此,接下来的的任务就是创建一些方法,这些方法允许我们构造并收集所有的限制条件到一个数组里。为此,我们有三个方法来返回每个UI 组件的限制条件到一个数组里。
我们还有一个方法,它将收集从这三个UI 组件返回的所有限制条件并将它们放进一个大的数组里。下面是我们如何实现它的:
我们还有一个方法,它将收集从这三个UI 组件返回的所有限制条件并将它们放进一个大的数组里。下面是我们如何实现它的:
- (NSArray *) emailTextFieldConstraints{ NSMutableArray *result = [[NSMutableArray alloc] init]; NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_textFieldEmail);//?? [result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:KEmailTextFieldHorizontal options:0 metrics:nil views:viewsDictionary]]; [result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:KEmailTextFieldVertical options:0 metrics:nil views:viewsDictionary]]; return [NSArray arrayWithArray:result]; }-(NSArray *)confirmEmailTextFieldConstraints{ NSMutableArray *result = [[NSMutableArray alloc] init]; NSDictionary *viewDictionary = NSDictionaryOfVariableBindings(_textFieldConfirmEmail,_textFieldEmail); [result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:KConfirmEmailHorizontal options:0 metrics:nil views:viewDictionary]]; [result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:KConfirmEmailVertical options:0 metrics:nil views:viewDictionary]]; return [NSArray arrayWithArray:result];}- (NSArray *) registerButtonConstraints{ NSMutableArray *result = [[NSMutableArray alloc] init]; NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_registerButton, _textFieldConfirmEmail); [result addObject: [NSLayoutConstraint constraintWithItem:self.registerButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f] ]; [result addObjectsFromArray: [NSLayoutConstraint constraintsWithVisualFormat:KRegisterVertical options:0 metrics:nil views:viewsDictionary] ]; return [NSArray arrayWithArray:result];}- (NSArray *) constraints{ NSMutableArray *result = [[NSMutableArray alloc] init]; [result addObjectsFromArray:[self emailTextFieldConstraints]]; [result addObjectsFromArray:[self confirmEmailTextFieldConstraints]]; [result addObjectsFromArray:[self registerButtonConstraints]]; return [NSArray arrayWithArray:result];}
这里需要注意一下,constraintsWithVisualFormat:options:metrics:views:方法和constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:方法返回的结果类型是不一样的,前者返回一个数组,后者返回的是一个id类型对象。
实际上这是视图控制器的限制条件实例方法,它将收集三个UI 组件的所有限制条件并将其返回到一个大的数组里。现在到了控制器的主要部分了,就是这个viewDidLoad 方法:
- (void)viewDidLoad{ [super viewDidLoad]; [self constructUIComponents]; [self addUIComponentsToView:self.view]; [self.view addConstraints:[self constraints]];}/* Suport rotation of device to all orientation */-(NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskAll;}
这个方法简单的构造了这个UI,使用我们之前写的方法添加UI 组件和它们的限制条件到它们自身。最后,运行一下吧,然后旋转一下模拟器看看是不是符合要求。
上面的例子比较简单,几个view的父视图是相同,他们的约束均添加给父视图即可。其它情况的添加规则可以查看上一篇文章,有详细描述添加规则。
文中主要内容和代码均来自《iOS 6 Programming Cookbook》,感谢DevDiv热心网友自发组织翻译。
0 0
- 【iOS开发】---- iOS自动布局(二)
- iOS开发之自动布局(二)
- IOS自动布局二
- iOS开发之自动布局
- iOS 开发 - 自动布局记录
- 【iOS开发】---- iOS自动布局(一)
- IOS项目开发布局二
- ios 代码 自动布局(二)
- iOS开发-自动布局篇:史上最牛的自动布局教学!
- iOS开发-自动布局篇:史上最牛的自动布局教学!
- ios开发 - ios6 自动布局 1
- iOS开发技巧 autolayout自动布局
- IOS开发之自动布局相关问题
- iOS 开发学习40 自动布局约束
- IOS开发—UIScrollView自动布局
- iOS开发技巧之autolayout自动布局
- iOS开发之 AutoLayout自动布局
- iOS 开发之 AutoLayout 自动布局
- android自动化测试中hierarchyviewer和uiautomatorviewer获取控件信息的方式比对(1)
- centos6.4中文输入法
- 并发处理
- 信息战的乌云从大洋彼岸飘来
- 模式识别(五):K近邻分类器(KNN)
- 【iOS开发】---- iOS自动布局(二)
- 浙大2012上机 PAT 1033. To Fill or Not to Fill (25)
- python程序设计:基础1
- CloseHandle
- INSTALL_FAILED_SHARED_USER_INCOMPATIBLE 的问题
- ExtJs4开发动态编辑的表格
- jquery实现html超链接锚点之间的平滑效果
- 移,病毒木马
- POJ题目归类