如何适配?
- 不同版本适配
- 不同屏幕尺寸适配,不同屏幕方向(横竖屏)
点与像素
- 1、用户:屏幕是由无数个像素组成的,开发者:屏幕是由无数个点组成的,点又是由像素组成的
- 2、非retina与retina屏
- 非retina屏幕(3GS) : 1个点由1个像素组成
- retina屏幕:1个点由2 x 2个像素组成
设备分辨率
自动布局的多种方式
1、Autoresizing
都是
约束父子
关系, 所以Autoresizing只能约束父子控件之间的关系,不能约束兄弟
控件之间的关系-
方式一:storyboard实现
-
注意: Storyboard中勾选上左边, 就代表当前控件和父控件的左边的距离是固定的
-
-
方式二:纯代码实现
- 注意1:代码中的上下左右和Storyboard中的是相反的
- Storyboard中勾选上左边, -> 当前控件和父控件的左边的距离是固定的
- 代码中如果写上FlexibleLeftMargin,->当前控件和父控件的左边是可拉伸的
- 注意1:代码中的上下左右和Storyboard中的是相反的
规律
UIViewAutoresizingFlexibleLeftMargin // 左边可以伸缩
UIViewAutoresizingFlexibleRightMargin // 右边可以伸缩
UIViewAutoresizingFlexibleTopMargin // 顶部可以伸缩
UIViewAutoresizingFlexibleBottomMargin // 底部可以伸缩
// 以下两个和Storyboard中的是一样的
UIViewAutoresizingFlexibleWidth // 宽度可以伸缩
UIViewAutoresizingFlexibleHeight // 高度可以伸缩
- 代码实现,红色View随着其父控件的宽度与高度拉伸而拉伸
-
效果:
-
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 1.创建父控件
UIView *greenView = [[UIView alloc] init];
greenView.frame = CGRectMake(0, 0, 200, 200);
greenView.backgroundColor = [UIColor greenColor];
[self.view addSubview:greenView];
self.greenView = greenView;
// 2.创建子控件
UIView *redView = [[UIView alloc] init];
redView.frame = CGRectMake(0, 0, 100, 100);
redView.backgroundColor = [UIColor redColor];
[greenView addSubview:redView];
// 3.设置子控件的autoresizing
// 红色子控件,随着父控件,宽度与高度可拉伸
redView.autoresizingMask = UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
}
- (void)touchesBegan:(nonnull NSSet *)touches withEvent:(nullable UIEvent *)event
{
self.greenView.frame = CGRectMake(0, 0, 300, 300);
}
-
点击视图,让父控件宽高增大,子控件也随父控件拉伸了
Autolayout 自动布局
1、Autolayout 代码实现
- 在创建约束之后,需要将其添加到作用的view上
- 约束规则
-
对于两个同层级view之间的约束关系,添加到它们的父view上
-
对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
-
-
对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
- 一个NSLayoutConstraint对象就代表一个约束
- 创建约束对象的常用方法
+(id)constraintWithItem:(id)view1attribute:(NSLayoutAttribute)attr1relatedBy:(NSLayoutRelation)relationtoItem:(id)view2attribute:(NSLayoutAttribute)attr2multiplier:(CGFloat)multiplierconstant:(CGFloat)c;
- 自动布局的核心计算公式
obj1.property1=(obj2.property2* multiplier)+constantvalue
需求:设置一个redView宽高100,现实在屏幕中间
+代码实现Autolayout的注意点
- 1、如果通过代码来设置Autolayout约束, 那么必须先禁用Autoresizing
```objc
redView.translatesAutoresizingMaskIntoConstraints = NO;
- 2、通过代码添加Autolayout约束, 添加约束之前必须保证控件已经在父控件上了
- 3、不用再给view设置frame
+ 创建约束 方法分析: [NSLayoutConstraint constraintWithItem: .......]
```objc
/*
Item == first item
attribute == first item需要设置的约束类型
relatedBy == Relatio(等于)
toItem == Second item
attribute == Second item的约束类型
multiplier == 乘以
constant == 加上多少
*/
// redView 的 centerX = self.view的centerX * 1.0 + 0.0
NSLayoutConstraint *xCos = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0];
- 代码实现
// 1.创建控件
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
2、基于Autolayout的动画
- 注意: 强制更新界面:会更新当前控件和当前控件所有的子控件
[添加了约束的view layoutIfNeeded];
- 代码实现:动画
#import "ViewController.h"
@interface ViewController ()
// 约束
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *topCos;
@property (weak, nonatomic) IBOutlet UIView *redView;
@end
@implementation ViewController
- (void)touchesBegan:(nonnull NSSet *)touches withEvent:(nullable UIEvent *)event
{
self.topCos.constant += 150;
[UIView animateWithDuration:2.0 animations:^{
// 强制更新界面
// 会更新当前控件和当前控件所有的子控件
[self.redView layoutIfNeeded];
}];
}
@end
VFL添加约束
Visual Format Language,“可视化格式语言”,VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言
VFL示例
H:[cancelButton(72)]-12-[acceptButton(50)]
pcanelButton宽72,acceptButton宽50,它们之间间距12
H:[wideView(>=60@700)]
pwideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)
V:[redBox][yellowBox(==redBox)]
竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox
H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
水平方向上,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|”表示superview的边缘)
- VFL的使用
- 使用VFL来创建约束数组
pformat:VFL语句
popts:约束类型
pmetrics:VFL语句中用到的具体数值
pviews:VFL语句中用到的控件
+(NSArray*)constraintsWithVisualFormat:(NSString*)format options:(NSLayoutFormatOptions)optsmetrics:(NSDictionary*)metrics views:(NSDictionary*)views;
- 创建一个字典(内部包含VFL语句中用到的控件)的快捷宏定义
NSDictionaryOfVariableBindings(...)
Masonry 第三方框架
- 注意: 在Storyboard中约束是可以重复添加的, 通过Masonry添加约束也是可以重复的, 要注意重复添加导致的错误和冲突
- 添加、更新、移除约束
- 添加约束 makeConstraints:
- 每次都会添加新的约束, 也就是会导致重复添加
- 添加约束 makeConstraints:
[self.blueVeiw makeConstraints:^(MASConstraintMaker *make) {
// make.height.equalTo(100);
// }];
+ 更新约束 updateConstraints
- 特点: 如果没有设置过, 就添加一个新的,如果已经设置过了, 就更新以前设置的那一个
```objc
[self.blueVeiw updateConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(100);
}];
- 清空约束 remakeConstraints
[self.blueVeiw remakeConstraints:^(MASConstraintMaker *make) {
}];
- 1、添加简化宏定义
#import "ViewController.h"
//define this constant if you want to use Masonry without the 'mas_' prefix
#define MAS_SHORTHAND
// 只要添加这个宏, 就可以去掉Masonry框架中对象访问对象属性前面的mas_属性, 和方法前的mas_前缀
// 例如添加前的写法
/*
make.left.equalTo(self.view.mas_left).with.offset(20);
*/
// 例如添加后的写法
/*
make.left.equalTo(self.view.left).with.offset(20);
*/
//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS
// 只要添加上这个宏, 给equalTo传递参数的时候, 就可以直接传递基本数据类型 ,系统会自动包装
// 如果没有添加上面这个宏, 那么给equalTo传递参数的时候, 必须传递对象
// 如果要传递基本数据类型必须使用mas_equalTo
// 只需要在导入Masonry.h之前, 添加上面的两个宏, 就可以简化代码
#import "Masonry.h"
-
2、实现红色view是蓝色宽度一半。。。。
// 1.创建两个View, 并且添加到父控件
UIView *blueVeiw = [[UIView alloc] init];
blueVeiw.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueVeiw];
self.blueVeiw = blueVeiw;
UIView *redVeiw = [[UIView alloc] init];
redVeiw.backgroundColor = [UIColor redColor];
[self.view addSubview:redVeiw];
// 2.禁止红色View的Autgoresizing
blueVeiw.translatesAutoresizingMaskIntoConstraints = NO;
redVeiw.translatesAutoresizingMaskIntoConstraints = NO;
// 3.添加蓝色的约束
[blueVeiw makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view.left).offset(20);
make.right.equalTo(self.view.right).offset(-20);
make.top.equalTo(self.view.top).offset(20);
make.height.equalTo(50);
}];
// 4.添加红色的约束
[redVeiw makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(blueVeiw.bottom).offset(20);
make.height.equalTo(blueVeiw.height);
make.right.equalTo(blueVeiw.right);
make.width.equalTo(blueVeiw.width).multipliedBy(0.5);
}];
sizeClasses
sizeclasses的组成: Compact/Regular/Any
图片中的设置: height = Any & compact
代表宽度是任意的, 高度是紧凑的
*==Any
- ==Compact
+ ==Regular
前面的是宽度, 后面的是高度
Any: 任意的
compact: 紧凑的
Regular:正常的