一、开始
关于iOS界面实现方式,目前有三种,xib 和 storyboard 以及 纯代码 编写,有各自的优缺点。
至于到底用什么来实现,可以看下唐大神的这篇文章,按需使用。
我之所以选择用纯代码编写UI界面,一方面是写Android的时候习惯了XML编写界面的方式,
另一方面是我对 xib 和 storyboard 不够熟悉,实现稍微复杂的界面,感觉无从下手。
因为要适配多个屏幕,需要用到autolayout,关于autolayout的常规知识,还是要有的,可以看下这两篇经典的文章:
我对于autolayout 的理解基本源于这两篇文章。
二、使用 Masonry 编写UI界面
autolayout 可以用 VFL 语言写,不过这个语法很坑爹,不容易上手;或者 初始化后用 NSLayoutConstraint 实现布局约束。
一番寻觅,找到这篇文章教程,介绍了Masonry,总算是入了门,从此爱上Masonry。
Masonry 对 autolayout 使用进行了封装,变得简单易懂,可读性强。
基本属性
MASViewAttribute | NSLayoutAttribute | 对应注释 |
---|---|---|
view.mas_left | NSLayoutAttributeLeft | 左侧 |
view.mas_right | NSLayoutAttributeRight | 右侧 |
view.mas_top | NSLayoutAttributeTop | 上方 |
view.mas_bottom | NSLayoutAttributeBottom | 下方 |
view.mas_leading | NSLayoutAttributeLeading | 首部 |
view.mas_trailing | NSLayoutAttributeTrailing | 尾部 |
view.mas_width | NSLayoutAttributeWidth | 宽度 |
view.mas_height | NSLayoutAttributeHeight | 高度 |
view.mas_centerX | NSLayoutAttributeCenterX | X轴中心 |
view.mas_centerY | NSLayoutAttributeCenterY | Y轴中心 |
view.mas_baseline | NSLayoutAttributeBaseline | 文本基线 |
基本方法
MASViewAttribute | NSLayoutAttribute | 对应注释 |
---|---|---|
.equalTo | NSLayoutRelationEqual | 等于 |
.lessThanOrEqualTo | NSLayoutRelationLessThanOrEqual | 小于等于 |
.greaterThanOrEqualTo | NSLayoutRelationGreaterThanOrEqual | 大于等于 |
可以控制 edges、size、center
提供三种约束方法
mas_makeConstraints 设置约束
mas_updateConstraints 更新约束
mas_remakeConstraints 删除约束
用起来很Android的布局差不多,都基于相对位置
请举一反三使用
// 约束
[self.text mas_makeConstraints:^(MASConstraintMaker *make){
make.top.equalTo(self.mas_top); // 控件上方对齐主视图上方
make.left.equalTo(self.mas_left).offset(10); // 控件左边对齐主视图左边,右位移10
make.bottom.equalTo(self.mas_bottom).offset(-5); // 控件底部对齐主视图,上位移5
// 上下 offset,正数向下位移,负数向上位移
// 左右 offset,正数向右位移,负数向左位移
make.edges.equalTo(self).insets(UIEdgeInsetsMake(5, 10, 15, 20)); // 边距(上、左、下、右)按逆时针方向
make.width.mas_equalTo(100); // mas_equalTo 设置一个固定值
make.center.equalTo(self); // 居中
make.centerX.equalTo(imageView); // 控件X轴对齐imageView控件的X轴
}];
简单使用例子
// 图片
self.image = [[UIImageView alloc] init];
self.image.image = [UIImage imageNamed:@"loading"];
self.image.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:self.image];
// 课程
self.lblCourse = [[UILabel alloc] init];
self.lblCourse.text = @"测试数据";
self.lblCourse.font = [UIFont systemFontOfSize:15.0];
self.lblCourse.textColor = [UIColor colorWithRed:51.0f/255.0f green:51.0f/255.0f blue:51.0f/255.0f alpha:1.0f];
self.lblCourse.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:self.lblCourse];
// 机构
self.btnOrg = [UIButton buttonWithType:UIButtonTypeCustom];
[self.btnOrg setTitle:@"测试数据" forState:UIControlStateNormal];
[self.btnOrg setTitleColor:[UIColor colorWithRed:102.0f/255.0f green:102.0f/255.0f blue:102.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];
self.btnOrg.titleLabel.font = [UIFont systemFontOfSize:14.0];
self.btnOrg.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
self.btnOrg.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:self.btnOrg];
// 最新课程
self.btnNewCourse = [UIButton buttonWithType:UIButtonTypeCustom];
[self.btnNewCourse setImage:[UIImage imageNamed:@"triangle_right"] forState:UIControlStateNormal];
[self.btnNewCourse setTitle:@"最新开班课程" forState:UIControlStateNormal];
[self.btnNewCourse setTitleColor:[UIColor colorWithRed:78.0f/255.0f green:187.0f/255.0f blue:197.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];
self.btnNewCourse.titleLabel.font = [UIFont systemFontOfSize:14.0];
self.btnNewCourse.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:self.btnNewCourse];
// 市场价
UILabel *lblPrefix = [[UILabel alloc] init];
lblPrefix.text = @"市场价:";
lblPrefix.font = [UIFont systemFontOfSize:14.0];
lblPrefix.textColor = [UIColor colorWithRed:152.0f/255.0f green:152.0f/255.0f blue:152.0f/255.0f alpha:1.0f];
lblPrefix.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:lblPrefix];
// 原价
self.lblOldPrice = [[UILabel alloc] init];
self.lblOldPrice.text = @"¥999";
self.lblOldPrice.font = [UIFont systemFontOfSize:14.0];
self.lblOldPrice.textColor = [UIColor colorWithRed:152.0f/255.0f green:152.0f/255.0f blue:152.0f/255.0f alpha:1.0f];
self.lblOldPrice.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:self.lblOldPrice];
// 现价
self.lblPrice = [[UILabel alloc] init];
self.lblPrice.text = @"¥888";
self.lblPrice.font = [UIFont systemFontOfSize:14.0];
self.lblPrice.textColor = [UIColor colorWithRed:255.0/255.0f green:100.0f/255.0f blue:122.0/255.0f alpha:1.0f];
self.lblPrice.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:self.lblPrice];
// 屏幕宽
CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;
// image 约束
[self.image mas_makeConstraints:^(MASConstraintMaker *make){
make.top.equalTo(self.mas_top).offset(5);
make.left.equalTo(self.mas_left).offset(10);
make.bottom.equalTo(self.mas_bottom).offset(-5);
make.width.mas_equalTo(screenWidth / 3 - 10);
make.height.mas_equalTo(75);
}];
// lblCourse 约束
[self.lblCourse mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.image.mas_top);
make.left.equalTo(self.image.mas_right).offset(10);
make.right.equalTo(self.mas_right).offset(-10);
}];
// btnOrg 约束
[self.btnOrg mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.lblCourse.mas_bottom);
make.left.equalTo(self.image.mas_right).offset(10);
make.right.equalTo(self.mas_right).offset(-10);
make.height.mas_equalTo(22);
}];
// btnNewCourse 约束
[self.btnNewCourse mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.btnOrg.mas_bottom);
make.left.equalTo(self.image.mas_right).offset(10);
}];
// lblPrefix 约束
[lblPrefix mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.btnNewCourse.mas_bottom);
make.left.equalTo(self.image.mas_right).offset(10);
}];
// lblOldPrice 约束
[self.lblOldPrice mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.btnNewCourse.mas_bottom);
make.left.equalTo(lblPrefix.mas_right);
}];
// lblPrice 约束
[self.lblPrice mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.btnNewCourse.mas_bottom);
make.right.equalTo(self.mas_right).offset(-10);
}];
效果图
更详细的可以查看官方Demo,玩得愉快 ^_^