Masonry使用注意篇.docx
《Masonry使用注意篇.docx》由会员分享,可在线阅读,更多相关《Masonry使用注意篇.docx(6页珍藏版)》请在冰豆网上搜索。
![Masonry使用注意篇.docx](https://file1.bdocx.com/fileroot1/2022-11/23/48a654a5-324f-4c99-b2c2-a27797623eae/48a654a5-324f-4c99-b2c2-a27797623eae1.gif)
Masonry使用注意篇
Masonry使用注意篇
简要
自动布局最重要的是约束:
UI元素间关系的数学表达式。
约束包括尺寸、由优先级和阈值管理的相对位置。
它们是添加剂,可能导致约束冲突、约束不足造成布局无法确定。
这两种情况都会产生异常。
使用前:
AutoLayout关于更新的几个方法的区别
setNeedsLayout:
告知页面需要更新,但是不会立刻开始更新。
执行后会立刻调用layoutSubviews。
layoutIfNeeded:
告知页面布局立刻更新。
所以一般都会和setNeedsLayout一起使用。
如果希望立刻生成新的frame需要调用此方法,利用这点一般布局动画可以在更新布局后直接使用这个方法让动画生效。
layoutSubviews:
系统重写布局
setNeedsUpdateConstraints:
告知需要更新约束,但是不会立刻开始
updateConstraintsIfNeeded:
告知立刻更新约束
updateConstraints:
系统更新约束
使用
1.基本使用
mas_makeConstraints:
添加约束
mas_updateConstraints:
更新约束、亦可添加新约束
mas_remakeConstraints:
重置之前的约束
multipler属性表示约束值为约束对象的乘因数,dividedBy属性表示约束值为约束对象的除因数,可用于设置view的宽高比
//进行屏幕的适配的时候,往往需要根据屏幕宽度来适配一个相应的高度,在此推荐使用如下约束的方式来进行控件的适配
[self.topViewaddSubview:
self.topInnerView];
[self.topInnerViewmas_makeConstraints:
^(MASConstraintMaker*make){
make.height.equalTo(self.topView.mas_height).dividedBy(3);
make.width.and.height.lessThanOrEqualTo(self.topView);
make.width.and.height.equalTo(self.topView).with.priorityLow();
make.center.equalTo(self.topView);
}];priorityLow()设置约束优先级
#defineMAS_SHORTHAND_GLOBALS使用全局宏定义,可以使equalTo等效于mas_equalTo
#defineMAS_SHORTHAND使用全局宏定义,可以在调用masonry方法的时候不使用mas_前缀
//这里注意到一个地方,就是当使用了这个全局宏定义之后,发现可以有个类`NSArray+MASAdditions.h`,看了之后发现可以
self.buttonViews=@[raiseButton,lowerButton,centerButton];
//之后可以在updateConstraints方法中
-(void)updateConstraints{
[self.buttonViewsupdateConstraints:
^(MASConstraintMaker*make){
make.baseline.equalTo(self.mas_centerY).with.offset(self.offset);
}];
[superupdateConstraints];
}
动态修改视图约束:
//创建视图约束
[blueViewmas_makeConstraints:
^(MASConstraintMaker*make){
self.animatableConstraint=make.edges.equalTo(superview).insets(paddingInsets).priorityLow();
]];
//更改约束(另一处方法中)
UIEdgeInsetspaddingInsets=UIEdgeInsetsMake(padding,padding,padding,padding);
self.animatableConstraint.insets=paddingInsets;
[selflayoutIfNeeded];debug模式:
//对某个view添加key值
greenView.mas_key=@"greenView";
//或者如下顺序
MASAttachKeys(greenView,redView,blueView,superview);
//同样的对每条约束亦可以添加key
make.height.greaterThanOrEqualTo(@5000).key(@"ConstantConstraint");preferredMaxLayoutWidth:
多行label的约束问题
//已经确认好了位置
//在layoutSubviews中确认label的preferredMaxLayoutWidth值
-(void)layoutSubviews{
[superlayoutSubviews];
//你必须在[superlayoutSubviews]调用之后,longLabel的frame有值之后设置preferredMaxLayoutWidth
self.longLabel.preferredMaxLayoutWidth=self.frame.size.width-100;
//设置preferredLayoutWidth后,需要重新布局
[superlayoutSubviews];
}scrollView使用约束的问题:
原理通过一个contentView来约束scrollView的contentSize大小,也就是说以子控件的约束条件,来控制父视图的大小
//1.控制scrollView大小(显示区域)
[self.scrollViewmakeConstraints:
^(MASConstraintMaker*make){
make.edges.equalTo(self.view);
}];
//2.添加一个contentView到scrollView,并且添加好约束条件
[contentViewmakeConstraints:
^(MASConstraintMaker*make){
make.edges.equalTo(self.scrollView);
//注意到此处的宽度约束条件,这个宽度的约束条件是比添加项
make.width.equalTo(self.scrollView);
}];
//3.对contentView的子控件做好约束,达到可以控制contentView的大小
新方法:
2个或2个以上的控件等间隔排序
/**
*多个控件固定间隔的等间隔排列,变化的是控件的长度或者宽度值
*
*@paramaxisType轴线方向
*@paramfixedSpacing间隔大小
*@paramleadSpacing头部间隔
*@paramtailSpacing尾部间隔
*/
-(void)mas_distributeViewsAlongAxis:
(MASAxisType)axisType
withFixedSpacing:
(CGFloat)fixedSpacingl
eadSpacing:
(CGFloat)leadSpacing
tailSpacing:
(CGFloat)tailSpacing;
/**
*多个固定大小的控件的等间隔排列,变化的是间隔的空隙
*
*@paramaxisType轴线方向
*@paramfixedItemLength每个控件的固定长度或者宽度值
*@paramleadSpacing头部间隔
*@paramtailSpacing尾部间隔
*/
-(void)mas_distributeViewsAlongAxis:
(MASAxisType)axisType
withFixedItemLength:
(CGFloat)fixedItemLength
leadSpacing:
(CGFloat)leadSpacing
tailSpacing:
(CGFloat)tailSpacing;
使用方法很简单,因为它是NSArray的类扩展:
//创建水平排列图标arr中放置了2个或连个以上的初始化后的控件
//alongAxis轴线方向固定间隔头部间隔尾部间隔
[arrmas_distributeViewsAlongAxis:
MASAxisTypeHorizontalwithFixedSpacing:
20leadSpacing:
5tailSpacing:
5];
[arrmas_makeConstraints:
^(MASConstraintMaker*make){
make.top.equalTo(@60);
make.height.equalTo(@60);
}];
2.注意事项
约束视图对象只有在被addSubview之后,才能给视图添加约束
当你的所有约束都在updateConstraints内调用的时候,你就需要在此调用此方法,因为updateConstraints方法是需要触发的
//调用在view内部,而不是viewcontroller
+(BOOL)requiresConstraintBasedLayout{
returnYES;
}
/**
*苹果推荐约束增加和修改放在此方法种
*/
-(void)updateConstraints{
[self.growingButtonupdateConstraints:
^(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方法
[superupdateConstraints];
}
如果想要约束变换之后实现动画效果,则需要执行如下操作
//通知需要更新约束,但是不立即执行
[selfsetNeedsUpdateConstraints];
//立即更新约束,以执行动态变换
//updateconstraintsnowsowecananimatethechange
[selfupdateConstraintsIfNeeded];
//执行动画效果,设置动画时间
[UIViewanimateWithDuration:
0.4animations:
^{
[selflayoutIfNeeded];
}];