一、基本用法
UIEdgeInsets edge = UIEdgeInsetsMake(10, 10, 10, 10);
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(view.superview).insets(edge);
}];
//.分别设置各个相对边距(superview为view的父类视图,下同)
make.left.mas_equalTo(superView.mas_left).mas_offset(10);
make.right.mas_equalTo(superView.mas_right).mas_offset(-10);
make.top.mas_equalTo(superView.mas_top).mas_offset(10);
make.bottom.mas_equalTo(superView.mas_bottom).offset(-10);
//直接连接使用left大于等于某个值 小于某个值 @10和10 mas_包装了一层
make.left.mas_greaterThanOrEqualTo(10);
make.left.lessThanOrEqualTo(@10)
//设置宽和高
make.width.mas_equalTo(60);
make.height.mas_equalTo(60);
//.设置center和款高比
make.center.mas_equalTo(superView);
make.width.mas_equalTo(superView).multipliedBy(1.00/3);
make.height.mas_equalTo(superView).multipliedBy(0.25);
//.关于约束优先级,此处要注意约束冲突的问题,统一约束优先级大的生效
make.left.mas_equalTo(100);
make.left.mas_equalTo(view.superview.mas_left).offset(10);
make.left.mas_equalTo(20).priority(700);
make.left.mas_equalTo(40).priorityHigh();
make.left.mas_equalTo(60).priorityMedium();
make.left.mas_equalTo(80).priorityLow();
//.如果你想让view的(x坐标)左边大于等于label的左边,以下两个约束的写法效果一样
make.left.greaterThanOrEqualTo(label);
make.left.greaterThanOrEqualTo(label.mas_left);
make.top.mas_equalTo(42);
make.height.mas_equalTo(20);
make.size.mas_equalTo(CGSizeMake(50, 100));
make.edges.mas_equalTo(UIEdgeInsetsMake(10, 0, 10, 0));
make.left.mas_equalTo(view).mas_offset(UIEdgeInsetsMake(10, 0, 10, 0));
// 宽度岛屿200 小于400
make.width.greaterThanOrEqualTo(@200);
make.width.lessThanOrEqualTo(@400)
一个数组,里面可以混合是前述三种类型的任意几种:
// 表达三个视图等高的约束.
make.height.equalTo(@[view1.mas_height, view2.mas_height]);
make.height.equalTo(@[view1, view2]);
make.left.equalTo(@[view1, @100, view3.right]);
1、长度关系和位置关系,不能做比例运算。
举几个例子
我现在希望子视图的横向中心线(centerY)在高度的1/5处,一般的想法是
make.centerY.mas_equalTo(self.height).multipliedBy(0.2);
运行出错。
正确的做法是
make.centerY.mas_equalTo(self.bottom).multipliedBy(0.2);
同理,我想子视图的垂直中心线(centerX)在宽的1/5处,应为
make.centerX.mas_equalTo(self.right).dividedBy(5);
子视图的top距离父视图的top是父视图的高度的0.8
make.top.equalTo(self.imageV.mas_bottom).multipliedBy(90.0/140.0); top 相对的师父控件和sef.imageV的top不一样。 要考虑到差值 make.top.equalTo(self.imageV.mas_bottom).offect(10 (也需要比例系数或者直接添加大self。image 上面)).multipliedBy(90.0/140.0);
2、等间距布局
使用mansonry 数组的扩展
/**
* 多个控件固定间隔的等间隔排列,变化的是控件的长度或者宽度值
*
* @param axisType 轴线方向
* @param fixedSpacing 间隔大小
* @param leadSpacing 头部间隔
* @param tailSpacing 尾部间隔
*/
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType
withFixedSpacing:(CGFloat)fixedSpacing l
eadSpacing:(CGFloat)leadSpacing
tailSpacing:(CGFloat)tailSpacing;
/**
* 多个固定大小的控件的等间隔排列,变化的是间隔的空隙
*
* @param axisType 轴线方向
* @param fixedItemLength 每个控件的固定长度或者宽度值
* @param leadSpacing 头部间隔
* @param tailSpacing 尾部间隔
*/
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType
withFixedItemLength:(CGFloat)fixedItemLength
leadSpacing:(CGFloat)leadSpacing
tailSpacing:(CGFloat)tailSpacing;
3、动画页面更新
setNeedsLayout:告知页面需要更新,但是不会立刻开始更新。执行后会立刻调用layoutSubviews。
layoutIfNeeded:告知页面布局立刻更新。所以一般都会和setNeedsLayout一起使用。如果希望立刻生成新的frame需要调用此方法,利用这点一般布局动画可以在更新布局后直接使用这个方法让动画生效。
layoutSubviews:系统重写布局
setNeedsUpdateConstraints:告知需要更新约束,但是不会立刻开始
updateConstraintsIfNeeded:告知立刻更新约束
updateConstraints:系统更新约束
2. 注意事项
约束视图对象只有在被addSubview之后,才能给视图添加约束
当你的所有约束都在 updateConstraints 内调用的时候,你就需要在此调用此方法,因为 updateConstraints方法是需要触发的
// 调用在view 内部,而不是viewcontroller
+ (BOOL)requiresConstraintBasedLayout {
return YES;
}
/**
* 苹果推荐 约束 增加和修改 放在此方法种
*/
- (void)updateConstraints {
[self.growingButton updateConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self);
make.width.equalTo(@(self.buttonSize.width)).priorityLow();
make.height.equalTo(@(self.buttonSize.height)).priorityLow();
make.width.lessThanOrEqualTo(self);
make.height.lessThanOrEqualTo(self);
}];
//最后记得回调super方法
[super updateConstraints];
}
4、约束优先级
约束的优先级
.priority 允许你指定一个精确的优先级,数值越大优先级越高.最高1000.
.priorityHigh 等价于 UILayoutPriorityDefaultHigh.优先级值为 750.
.priorityMedium 介于高优先级和低优先级之间,优先级值在 250~750之间.
.priorityLow 等价于 UILayoutPriorityDefaultLow, 优先级值为 250.
5、scroller上使用
UIScrollView *scrollView = [UIScrollView new];
scrollView.backgroundColor = [UIColor whiteColor];
[sv addSubview:scrollView];
[scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(sv).with.insets(UIEdgeInsetsMake(5,5,5,5));
}];
UIView *container = [UIView new];
[scrollView addSubview:container];
[container mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(scrollView);
make.width.equalTo(scrollView);
}];
int count = 10;
UIView *lastView = nil;
for ( int i = 1 ; i <= count ; ++i )
{
UIView *subv = [UIView new];
[container addSubview:subv];
subv.backgroundColor = [UIColor colorWithHue:( arc4random() % 256 / 256.0 )
saturation:( arc4random() % 128 / 256.0 ) + 0.5
brightness:( arc4random() % 128 / 256.0 ) + 0.5
alpha:1];
[subv mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.right.equalTo(container);
make.height.mas_equalTo(@(20*i));
if ( lastView )
{
make.top.mas_equalTo(lastView.mas_bottom);
}
else
{
make.top.mas_equalTo(container.mas_top);
}
}];
lastView = subv;
}
[container mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(lastView.mas_bottom);
}];
参考
https://blog.csdn.net/hherima/article/details/53318306
https://www.jianshu.com/p/7798585755cc
https://www.jianshu.com/p/2262dfaf46e9
- [高级] 横向或者纵向等间隙的排列一组view
摘自https://www.cnblogs.com/wangbinios/p/5716887.html
书籍:Masonry介绍与使用实践.pdf
很遗憾 autoLayout并没有直接提供等间隙排列的方法(Masonry的官方demo中也没有对应的案例) 但是参考案例3 我们可以通过一个小技巧来实现这个目的 为此我写了一个Category// 注释现在有了
@implementation UIView(Masonry_LJC)
- (void) distributeSpacingHorizontallyWith:(NSArray*)views
{
NSMutableArray *spaces = [NSMutableArray arrayWithCapacity:views.count+1];
for ( int i = 0 ; i < views.count+1 ; ++i )
{
UIView *v = [UIView new];
[spaces addObject:v];
[self addSubview:v];
[v mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(v.mas_height);
}];
}
UIView *v0 = spaces[0];
__weak __typeof(&*self)ws = self;
[v0 mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(ws.mas_left);
make.centerY.equalTo(((UIView*)views[0]).mas_centerY);
}];
UIView *lastSpace = v0;
for ( int i = 0 ; i < views.count; ++i )
{
UIView *obj = views[i];
UIView *space = spaces[i+1];
[obj mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(lastSpace.mas_right);
}];
[space mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(obj.mas_right);
make.centerY.equalTo(obj.mas_centerY);
make.width.equalTo(v0);
}];
lastSpace = space;
}
[lastSpace mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(ws.mas_right);
}];
}
- (void) distributeSpacingVerticallyWith:(NSArray*)views
{
NSMutableArray *spaces = [NSMutableArray arrayWithCapacity:views.count+1];
for ( int i = 0 ; i < views.count+1 ; ++i )
{
UIView *v = [UIView new];
[spaces addObject:v];
[self addSubview:v];
[v mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(v.mas_height);
}];
}
UIView *v0 = spaces[0];
__weak __typeof(&*self)ws = self;
[v0 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(ws.mas_top);
make.centerX.equalTo(((UIView*)views[0]).mas_centerX);
}];
UIView *lastSpace = v0;
for ( int i = 0 ; i < views.count; ++i )
{
UIView *obj = views[i];
UIView *space = spaces[i+1];
[obj mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(lastSpace.mas_bottom);
}];
[space mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(obj.mas_bottom);
make.centerX.equalTo(obj.mas_centerX);
make.height.equalTo(v0);
}];
lastSpace = space;
}
[lastSpace mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(ws.mas_bottom);
}];
}
@end
UIView *sv11 = [UIView new];
UIView *sv12 = [UIView new];
UIView *sv13 = [UIView new];
UIView *sv21 = [UIView new];
UIView *sv31 = [UIView new];
sv11.backgroundColor = [UIColor redColor];
sv12.backgroundColor = [UIColor redColor];
sv13.backgroundColor = [UIColor redColor];
sv21.backgroundColor = [UIColor redColor];
sv31.backgroundColor = [UIColor redColor];
[sv addSubview:sv11];
[sv addSubview:sv12];
[sv addSubview:sv13];
[sv addSubview:sv21];
[sv addSubview:sv31];
//给予不同的大小 测试效果
[sv11 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(@[sv12,sv13]);
make.centerX.equalTo(@[sv21,sv31]);
make.size.mas_equalTo(CGSizeMake(40, 40));
}];
[sv12 mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(70, 20));
}];
[sv13 mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(50, 50));
}];
[sv21 mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(50, 20));
}];
[sv31 mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(40, 60));
}];
[sv distributeSpacingHorizontallyWith:@[sv11,sv12,sv13]];
[sv distributeSpacingVerticallyWith:@[sv11,sv21,sv31]];
[sv showPlaceHolderWithAllSubviews];
[sv hidePlaceHolder];
效果
6、 mansonry九宫格布局
https://www.cnblogs.com/YHStar/p/5788896.html
http://ios.jobbole.com/89298/
7、立即绘制 如果下面需要用frame的话
[self setNeedsLayout];
[self layoutIfNeeded];