UIKit框架(8)屏幕适配(二)
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)view1attribute:(NSLayoutAttribute)attr1relatedBy:(NSLayoutRelation)relationtoItem:(id)view2attribute:(NSLayoutAttribute)attr2multiplier:(CGFloat)multiplierconstant:(CGFloat)c
参数即约束的核心公式
NSLayoutRelation枚举:
enum{NSLayoutRelationLessThanOrEqual=-1,NSLayoutRelationEqual=0,NSLayoutRelationGreaterThanOrEqual=1,};typedefNSIntegerNSLayoutRelation;
NSLayoutAttribute枚举:
typedefenum: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的动画:
代码中如果修改了约束的数值,则执行下面的代码,就能产生相应的动画效果。
[UIViewanimateWithDuration:1.0animations:^{[viewlayoutIfNeeded];}];
哪个view中的约束变化了,哪个view对象调用layoutIfNeed方法
约束的变化应在动画之前完成。
UILabel、UIButton这类显示文字的控件使用AutoLayout的好处:
使用了恰当的约束,能够使其尺寸自动匹配。
如设置了UILabel对象的上、左、右的规定边距,则UILabel的尺寸会根据文字自动适应。
约束的VFL方式
Visual Format Language,可视化格式语言,是苹果公司为了简化AutoLayout的编码而推出的抽象语言。
其实不能称之为“语言”,可以认为这仅仅是一种“语法”,其目的是减少代码使用AutoLayout的编程量
但实际减少的程度有限,有些约束的功能使用VFL也无法完成,但在实现一些简单约束时非常有效。
NSLayoutConstraint的另一个创建方法:
+(NSArray*)constraintsWithVisualFormat:(NSString*)formatoptions:(NSLayoutFormatOptions)optsmetrics:(NSDictionary*)metricsviews:(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.redViewzxp_addConstraints:^(ZXPAutoLayoutMaker*layout){}];
单个view的布局关系:
在superview中的内边距:
@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^topSpace)(CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^leftSpace)(CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^bottomSpace)(CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^rightSpace)(CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^edgeInsets)(UIEdgeInsetsinsets);
如:
[self.redViewzxp_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,CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^yCenterByView)(UIView*view,CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^centerByView)(UIView*view,CGFloatvalue);
参数view应为superview
宽高操作:
@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^widthValue)(CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^heightValue)(CGFloatvalue);
如:
[self.redViewzxp_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,CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^leftSpaceByView)(UIView*view,CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^bottomSpaceByView)(UIView*view,CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^rightSpaceByView)(UIView*view,CGFloatvalue);//当前top内边距值与view的相等@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^topSpaceByView)(UIView*view,CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^leftSpaceByView)(UIView*view,CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^bottomSpaceByView)(UIView*view,CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^rightSpaceByView)(UIView*view,CGFloatvalue);//与view等宽@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^widthEqualTo)(UIView*view,CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^heightEqualTo)(UIView*view,CGFloatvalue);
如:
[self.redViewzxp_addConstraints:^(ZXPAutoLayoutMaker*layout){layout.xCenterByView(self.view,0);layout.yCenterByView(self.view,-100);layout.widthValue(100);layout.heightValue(100);}];[self.blueViewzxp_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)(CGFloatvalue);@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^autoWidth)();@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^autoWidthByMin)(CGFloatvalue);
其他操作:
@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^priority)(UILayoutPrioritypriority);//优先级@property(copy,nonatomic,readonly)ZXPAutoLayoutMaker*(^multiplier)(CGFloatmultiplier);//约束的倍数
如:
[self.blueViewzxp_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);}];
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。