AutoLayout介绍
创新互联公司是一家集网站建设,郊区企业网站建设,郊区品牌网站建设,网站定制,郊区网站建设报价,网络营销,网络优化,郊区网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
AutoLayout的功能要比AutoResizing强大的多。
当对一个UIView对象使用了AutoLayout布局后,意味着放弃了通过对象的frame进行修改视图的位置、尺寸。
AutoLayout使约束条件,通过自动布局引擎,计算view对象的frame。
可以认为在AutoLayout中view对象的frame是一个只读的属性。
约束的核心公式:
view1.attr1 = (view2.attr2 * multiplier) + constraint
其中obj2可以是nil
除了=关系外,还可以是>= <=的关系
代码适配
添加约束的步骤:
1)禁止被适配view的AutoResizing功能
- (BOOL)translatesAutoresizingMaskIntoConstraints - (void)setTranslatesAutoresizingMaskIntoConstraints:(BOOL)flag
2)创建约束对象NSLayoutConstraint
+ (instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c
参数即约束的核心公式
NSLayoutRelation枚举:
enum { NSLayoutRelationLessThanOrEqual = -1, NSLayoutRelationEqual = 0, NSLayoutRelationGreaterThanOrEqual = 1, }; typedef NSInteger NSLayoutRelation;
NSLayoutAttribute枚举:
typedef enum: NSInteger { NSLayoutAttributeLeft = 1, NSLayoutAttributeRight, NSLayoutAttributeTop, NSLayoutAttributeBottom, NSLayoutAttributeLeading, NSLayoutAttributeTrailing, NSLayoutAttributeWidth, NSLayoutAttributeHeight, NSLayoutAttributeCenterX, NSLayoutAttributeCenterY, NSLayoutAttributeBaseline, NSLayoutAttributeLastBaseline = NSLayoutAttributeBaseline, NSLayoutAttributeFirstBaseline, NSLayoutAttributeLeftMargin, NSLayoutAttributeRightMargin, NSLayoutAttributeTopMargin, NSLayoutAttributeBottomMargin, NSLayoutAttributeLeadingMargin, NSLayoutAttributeTrailingMargin, NSLayoutAttributeCenterXWithinMargins, NSLayoutAttributeCenterYWithinMargins, NSLayoutAttributeNotAnAttribute = 0} NSLayoutAttribute;
3)在UIView对象上添加约束对象
- (void)addConstraint:(NSLayoutConstraint *)constraint - (void)addConstraints:(NSArray *)constraints
将约束添加到哪个view对象上应按照以下规则:
对于同级view之间的约束关系,添加到它们的父控件上
对于不同级view之间的约束关系,添加到最近的共同父控件上
对于有层级关系的两个view之间约束关系,添加到层次较高的的空间上
注意:约束不能重复添加,不能缺少必要的约束
添加约束的过程中非常容易出现无法计算出frame的情况
UIView的其他操作约束的方法:
- (NSArray *)constraints - (void)removeConstraint:(NSLayoutConstraint *)constraint - (void)removeConstraints:(NSArray *)constraints
AutoLayout的补充
AutoLayout的动画:
代码中如果修改了约束的数值,则执行下面的代码,就能产生相应的动画效果。
[UIView animateWithDuration:1.0 animations:^{ [view layoutIfNeeded]; }];
哪个view中的约束变化了,哪个view对象调用layoutIfNeed方法
约束的变化应在动画之前完成。
UILabel、UIButton这类显示文字的控件使用AutoLayout的好处:
使用了恰当的约束,能够使其尺寸自动匹配。
如设置了UILabel对象的上、左、右的规定边距,则UILabel的尺寸会根据文字自动适应。
约束的VFL方式
Visual Format Language,可视化格式语言,是苹果公司为了简化AutoLayout的编码而推出的抽象语言。
其实不能称之为“语言”,可以认为这仅仅是一种“语法”,其目的是减少代码使用AutoLayout的编程量
但实际减少的程度有限,有些约束的功能使用VFL也无法完成,但在实现一些简单约束时非常有效。
NSLayoutConstraint的另一个创建方法:
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary*)views
format参数:VFL语句
views参数:VFL中出现的对象“键值对”
metrics:占位符
返回一组约束对象
VFL语句示意:
如:
canelButton宽72,acceptButton宽50,它们之间间距12
H:[cancelButton(72)]-12-[acceptButton(50)]
wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)
H:[wideView(>=60@700)]
竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox
V:[redBox]-[yellowBox(==redBox)]
水平方向上,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|” 表示superview的边缘)
H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
ZXPAutoLayout
号称最轻巧的自动布局,简化了NSLayoutConstraint的繁琐,采用新颖的链式语法,可扩展性强,维护成为低。
使用 zxp_addAutoLayout添加布局, 如:
[self.redView zxp_addConstraints:^(ZXPAutoLayoutMaker *layout) { }];
单个view的布局关系:
在superview中的内边距:
@property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^topSpace)(CGFloat value); @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^leftSpace)(CGFloat value); @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^bottomSpace)(CGFloat value); @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^rightSpace)(CGFloat value); @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^edgeInsets)(UIEdgeInsets insets);
如:
[self.redView zxp_addConstraints:^(ZXPAutoLayoutMaker *layout) { //layout.topSpace(20); //layout.bottomSpace(30); //layout.leftSpace(40); //layout.rightSpace(50); layout.edgeInsets(UIEdgeInsetsMake(20, 30, 40, 50)); }];
居中操作:
@property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^xCenterByView)(UIView *view,CGFloat value); @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^yCenterByView)(UIView *view,CGFloat value); @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^centerByView)(UIView *view,CGFloat value);
参数view应为superview
宽高操作:
@property (copy,nonatomic,readonly) ZXPAutoLayoutMaker *(^widthValue)(CGFloat value); @property (copy,nonatomic,readonly) ZXPAutoLayoutMaker *(^heightValue)(CGFloat value);
如:
[self.redView zxp_addConstraints:^(ZXPAutoLayoutMaker *layout) { layout.xCenterByView(self.view, 0); layout.yCenterByView(self.view, -100); layout.widthValue(100); layout.heightValue(100); }];
两个view的布局关系:
//与另一个view的内边距相等 @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^edgeEqualTo)(UIView *view); //当前的top距离view为value点坐标距离 @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^topSpaceByView)(UIView *view,CGFloat value); @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^leftSpaceByView)(UIView *view,CGFloat value); @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^bottomSpaceByView)(UIView *view,CGFloat value); @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^rightSpaceByView)(UIView *view,CGFloat value); //当前top内边距值与view的相等 @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^topSpaceByView)(UIView *view,CGFloat value); @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^leftSpaceByView)(UIView *view,CGFloat value); @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^bottomSpaceByView)(UIView *view,CGFloat value); @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^rightSpaceByView)(UIView *view,CGFloat value); //与view等宽 @property (copy,nonatomic,readonly) ZXPAutoLayoutMaker *(^widthEqualTo)(UIView *view,CGFloat value); @property (copy,nonatomic,readonly) ZXPAutoLayoutMaker *(^heightEqualTo)(UIView *view, CGFloat value);
如:
[self.redView zxp_addConstraints:^(ZXPAutoLayoutMaker *layout) { layout.xCenterByView(self.view, 0); layout.yCenterByView(self.view, -100); layout.widthValue(100); layout.heightValue(100); }]; [self.blueView zxp_addConstraints:^(ZXPAutoLayoutMaker *layout) { layout.topSpaceByView(self.redView, 100); layout.heightEqualTo(self.redView, 0); layout.widthEqualTo(self.redView, 0); layout.leftSpaceEqualTo(self.redView, 0); }];
自适应操作:(对UILabel有效)
@property (copy,nonatomic,readonly) ZXPAutoLayoutMaker *(^autoHeight)(); @property (copy,nonatomic,readonly) ZXPAutoLayoutMaker *(^autoHeightByMin)(CGFloat value); @property (copy,nonatomic,readonly) ZXPAutoLayoutMaker *(^autoWidth)(); @property (copy,nonatomic,readonly) ZXPAutoLayoutMaker *(^autoWidthByMin)(CGFloat value);
其他操作:
@property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^priority)(UILayoutPriority priority); //优先级 @property (copy, nonatomic, readonly) ZXPAutoLayoutMaker *(^multiplier)(CGFloat multiplier); //约束的倍数
如:
[self.blueView zxp_addConstraints:^(ZXPAutoLayoutMaker *layout) { layout.topSpaceByView(self.redView, 100); layout.heightEqualTo(self.redView, 0).multiplier(0.5); layout.widthEqualTo(self.redView, 0); layout.leftSpaceEqualTo(self.redView, 0); }];