自动布局-MyLayout
一、简介
1、 MyLayout
是一套iOS界面视图布局框架。MyLayout
的内核是基于frame
的设置,对UIView
的layoutSubviews
方法的重载以及对子视图的bounds
和center
属性的设置而实现的。MyLayout
功能强大而且简单易用,它集成了:iOS Autolayout
和SizeClass
、android的5大布局体系、HTML/CSS的浮动定位技术以及flex-box和bootstrap框架等市面上主流的平台的界面布局功能,同时提供了一套非常简单和完备的多屏幕尺寸适配的解决方案
二、详解
(一)、线性布局(MyLinearLayout)
1、支持垂直布局(从上到下)和水平布局(从左到右)
2、可以通过调整间距和边距来调整子视图位置
3、可以通过equalizeSubviews
方法均分视图(不)居中
4、可以通过equalizeSubviewsSpace
方法均分间距(不)居中
5、可以通过setSubviewsSize
方法实现固定宽度浮动间距效果
6、可以通过gravity
控制布局视图里面的子视图停靠方向和子视图填充方式
(二)、框架布局(MyFrameLayout)
1、框架布局中的子视图可以层叠显示
2、框架布局里面的所有子视图的布局位置都只跟框架布局相关
(三)、相对布局(MyRelativeLayout)
1、子视图整体水平居中,通过为centerXPos等于一个数组值,子视图的间距通过offset来定义,如下
v1.centerXPos.equalTo(@[v2.centerXPos.offset(20)]);
2、子视图整体垂直居中,通过为centerYPos等于一个数组值,子视图的间距通过offset来定义,如下
v1.centerYPos.equalTo(@[v2.centerYPos.offset(20)]);
3、子视图宽度均分,通过widthSize等于一个数组值,如果子视图间有间距,需要add(-sapce),如下
a、v1、v2、v3均分父视图
v1.widthSize.equalTo(@[v2.widthSize.add(-10), v3.widthSize.add(-10)]).add(-10);
b、按比例均分的话, v7,v8,v9按照2:3:5的比例均分父视图。
v7.widthSize.equalTo(@[v8.widthSize.multiply(0.3).add(-10),v9.widthSize.multiply(0.5).add(-10)]).multiply(0.2).add(-10);
c、v4固定宽度,v5、v6均分
v5.widthSize.equalTo(@[v4.widthSize.add(-10), v6.widthSize.add(-10)]).add(-10);
4、子视图滚动和停靠,可以通过
noLayout
属性配合frame
来实现a、当
noLayout=YES
,布局约束失效,设置frame实现停靠b、当
noLayout=NO
,布局约束生效,frame属性失效,实现滚动- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{//testTopDockView的上面视图是testView1。所以这里如果偏移超过testView1的最大则开始固定testTopDockView了
if (scrollView.contentOffset.y > CGRectGetMaxY(self.testView1.frame))
{
self.testTopDockView.noLayout = YES;
CGRect rect = self.testTopDockView.frame;
self.testTopDockView.frame = CGRectMake(rect.origin.x, scrollView.contentOffset.y, rect.size.width, rect.size.height);
//这里可以自由设置位置和尺寸了。
}
else
{
//当滚动的偏移小于90后,我们将testTopDocView的noLayout设置回NO,这样这个视图就又会根据所设置的约束而受到布局视图的约束和控制了,这时候frame的设置将不再起作用了。
self.testTopDockView.noLayout = NO;
}
}
5、边界约束,可通过
uBound
最大值约束和lBound
最小值约束,来约束子视图不能大于或者小于父容器、不能大于或者小于兄弟视图的上、左、下、右中的某一边6、最值约束
a、
myMaxSize
,获取指定数组中最大尺寸值,如下//视图D的高度是: 视图A的宽度、视图B的高度、视图C的高度的一半、50 这四个值中的最大值。那么视图D的高度约束可以如下设置:
D.heightSize.equalTo(@[A.widthSize, B.heightSize, C.heightSize.clone(0, 0.5), @50].myMaxSize);
b、
myMinSize
,获取指定数组中最小尺寸值视图C的宽度是:自身宽度、视图B的宽度-20、30这三个值的最小值。
C.widthSize.equalTo(@(MyLayoutSize.wrap),B.widthSize.clone(-20,1),@30).myMinSize);
c、
myMaxPos
,获取指定数组中最大边距视图D的右边距是:视图A的左边距、视图B的右边距、视图C的左边距偏移20、50这四个值中的最大值。那么视图D的右边距约束可以如下设置:
D.rightPos.equalTo(@[A.leftPos,B.rightPos,C.leftPos.clone(20), @50].myMaxPos)
d、
myMinPos
,获取指定数组中最小边距(四)、表格布局(MyTableLayout) 1、需要先添加行,才能添加列
2、
MyLayoutSize.average
设置均分效果a、高度固定,宽度均分
[tableLayout addRow:50 colSize:MyLayoutSize.average];
b、高度均分,宽度均分
[tableLayout addRow:MyLayoutSize.average colSize:MyLayoutSize.average];
3、
MyLayoutSize.wrap
设置高宽自适应a、高度有子视图决定,宽度均分
[tableLayout addRow:MyLayoutSize.wrap colSize:MyLayoutSize.average];
b、高度固定,子视图自己决定宽度
[tableLayout addRow:30 colSize:MyLayoutSize.wrap];
4、指定列宽度固定,其他列均分宽度,通过
MyLayoutSize.fill
和weight
配合使用[tableLayout addRow:30 colSize:MyLayoutSize.fill];
MyFrameLayout *cellLayout = [[MyFrameLayout alloc] init];
cellLayout.myWidth = 80;
[tableLayout addSubview:cellLayout];
for (NSInteger i = 0;
i < 3;
i++) {
MyFrameLayout *cellLayout2 = [[MyFrameLayout alloc] init];
cellLayout2.weight = 1;
[tableLayout addSubview: cellLayout2];
}
(五)、流式布局(MyFlowLayout) 1、流式布局中的子视图总是按一定的规则一次排列,当数量到达一定程度或者内容到达一定程度时就会自动换行从新排列
2、
MyLayoutDragger
实现标签拖拽功能3、
arrangedCount
为0时,就是根据内容布局4、分页滚动
//1、如果父控件是UIScrollView时,父UIScrollView 的delaysContentTouches需要设置为NO,这样就会优先处理子滚动视图的事件
//2、MyFlowLayout所在的UIScrollView的pagingEnabled需要设置为YES
//3、pagedCount的个数必须为arrangedCount的倍数UIScrollView *parentView = [UIScrollView new];
parentView.delaysContentTouches = NO;
...
UIScrollView *contentScrollView = [UIScollView new];
contentScrollView. pagingEnabled = YES;
...
[parentView addSubview: contentScrollView];
//建立一个水平数量约束流式布局:每列展示3个子视图,每页展示9个子视图,整体从左往右滚动
MyFlowLayout *flowLayout = [MyFlowLayout flowLayoutWithOrientation:MyOrientation_Horz arrangedCount:3];
flowLayout.pagedCount = 9;
flowLayout.myWidth = MyLayoutSize.wrap;
flowLayout.heightSize.equalTo(scrollView.heightSize);
//如果设置为如下的话,变为整体从上往下滚动
//flowLayout.myHeight = MyLayoutSize.wrap;
//flowLayout.widthSize.equalTo(scrollView.widthSize);
...
[contentScrollView addSubView:flowLayout];
...
【自动布局-MyLayout】5、通过
lineGravity
属性可以设置某行的对齐方式(六)、Flex布局(MyFlexLayout) (七)、浮动布局(MyFloatLayout) 1、浮动布局是一种里面的子视图按照约定的方向浮动停靠,当浮动布局的剩余空间不足容纳要加入的子视图的尺寸时会自动寻找最佳的位置进行浮动停靠的布局视图。因此浮动布局可以专门用来实现那些不规则布局或者图文环绕的布局。
2、
reverseFloat
反向浮动3、
clearFloat
清除浮动,另起一行重新排列4、
setSubviewsSize
设置固定宽度浮动间距5、
alignment
设置其在浮动布局行(列)内的对齐方式(八)、路径布局(MyPathLayout) 1、布局三要素:坐标、函数、距离
(九)、栅格布局(MyGridLayout) 1、栅格布局是一种将一个矩形的视图区域按行或者按列的方式划分为多个子区域,子区域根据布局的要求可以继续递归划分。栅格布局里面的子视图将按照添加的顺序依次填充到对应的叶子区域中去的布局方式。
栅格布局通过一套自定义的布局体系来划分位置和尺寸,添加到栅格布局里面的子视图将不再需要指定位置和尺寸而是由栅格布局中的子栅格来完成,因此可以很很方便的调整布局结构,从而实现动态布局的能力
2、栅格布局主要用于布局和数据分离的场景,可以通过json数据来完成布局
推荐阅读
- python学习之|python学习之 实现QQ自动发送消息
- 使用composer自动加载类文件
- 人脸识别|【人脸识别系列】| 实现自动化妆
- Spring|Spring Boot 自动配置的原理、核心注解以及利用自动配置实现了自定义 Starter 组件
- 织网布局,社群营销走进山东玖零落地企业
- win7删除新建不自动刷新
- 浅析(成人情趣用品智能无人自动售货机是新零售的下一个风口吗())
- Java代码辅助效率工具Lombok(注解|Java代码辅助效率工具Lombok(注解,自动生成代码)
- 瀑布流布局
- 2018-12-03-新手教程重构思路