iOS页面布局及适配
一、固定布局frame(x, y, w, h)
UIEdgeInsets edge = UIEdgeInsetsMake(10, 10, 10, 10);
CGSize superSize = view.superview.frame.size;
CGFloat width = superSize.width - edge.left - edge.right;
CGFloat heitht = superSize.height - edge.top - edge.bottom;
view.frame = CGRectMake(edge.left, edge.top, width, heitht);
局限性:位置固定,不能随父view大小的改变而改变
二、Autoresizing Mask
enum {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin 自动调整与superView左边的距离,保证与左边的距离和右边的距离和原来距左边和右边的距离的比例不变。比如原来距离为20,30,调整后的距离应为60,90,即60/20=90/30。
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight比较常用。
适用性:让横竖屏适配相对简单
让子控件可以随父控件的行为发生相应的改变
局限性:只能解决子控件和父控件的相对关系问题, 不能解决兄弟控件的相对关系问题
三、AutoLayout
iOS6开始引入AutoLayout,是一种基于约束的、描述性的布局系统,主要功能是使用约束,对视图进行相对布局,以适应不同屏幕尺寸的变换及屏幕的旋转
iOS7时,因为只有3.5英寸及4英寸两种尺寸,宽度一样,高度不同,比较好适配,所以AutoLayout并没有普及。
iOS8时,添加了4.7英寸,三种屏幕尺寸,必须考虑适配问题。
[self addConstraints:@[ [NSLayoutConstraint constraintWithItem:self.cellScrollView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:10.0],
[NSLayoutConstraint constraintWithItem:self.cellScrollView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-10.0],
[NSLayoutConstraint constraintWithItem:self.cellScrollView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:10.0],
[NSLayoutConstraint constraintWithItem:self.cellScrollView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:-10.0]];
view1.attr1 = view2.attr2 * multiplier + constant
对于两个同层级view之间的约束关系,添加到他们的父view上
对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
容易出现的问题:
添加约束之前,一定要保证相关控件都已经在各自的父控件上, 否则crash
约束不够(添加必要的约束条件或者调整优先级)
约束出现冲突(删掉冲突的约束条件)
四、Masonry
Autolayout的方法太繁琐,Masonry框架可以让我们更轻松的为控件添加约束。
define MAS_SHORTHAND_GLOBALS使用全局宏定义,可以使equalTo等效于mas_equalTo
define MAS_SHORTHAND使用全局宏定义, 可以在调用masonry方法的时候不使用mas_前缀
1、Masonry使用方法
// 仅仅会添加新的约束
[myView mas_makeConstraints:^(MAConstraintMaker *make){
// 在这个block里面, 利用make对象为控件添加约束
make.size.mas_equalTo(CGSize(100, 100)); // 尺寸约束
make.center.mas_equalTo(self.view); // 位置约束: 居中
}];
// 将以前所有的约束都删掉, 重新添加约束
[myView mas_remakeConstraints:^(MAConstraintMaker *make){
}];
// 覆盖以前的某些特定的约束
[myView mas_updateConstraints:^(MAConstraintMaker *make){
}];
2、约束的类型
1.尺寸: width\height\size
2.边界: left\leading\right\trailing\top\bottom\edges
3.中心点: center\centerX\centerY\baseline
4.偏移量: offset\insets\sizeOffset\contentOffset
- priority()约束优先级(0~1000),multipler乘因数, dividedBy除因数
3、约束的关系
equalTo
lessThanOrEqualTo
greaterThanOrEqualTo
mas_equalTo:这个方法会对参数进行封装( 可以跟数据和对象 )
equalTo:这个方法不会对参数进行封装( 后面括号里面必须是对象 )
UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(superview.mas_top).with.offset(padding.top);
make.left.equalTo(superview.mas_left).with.offset(padding.left);
make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);
make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}];