从类的初始化方法中我们可以看出,在创建一个浮动布局时必须要指定一个方向,这个方向指的是最终子视图的布局走向,因为左右浮动布局我们是先按左右浮动最终是一个从上到下的排列过程,而上下浮动布局则是先按上下浮动最终则是从左到右排列,因此当我们指定orientation的值为MyLayoutViewOrientation_Vert表示的是创建一个左右浮动的浮动布局,而当值设定为MyLayoutViewOrientation_Horz时则表示建立的是一个上下浮动的浮动布局,系统默认建立的是左右浮动的浮动布局。而且后续还可以通过orientation属性来进行动态的修改浮动的方向。当浮动布局的浮动方向指定后,接下来我们就要为某个要添加到浮动布局的子视图指定浮动方向属性、清除浮动属性、以及比重了,这些则可以通过视图的扩展分类:
@interface UIView(MyFloatLayoutExt)
@property(nonatomic,assign,getter=isReverseFloat) IBInspectable BOOL reverseFloat;
@property(nonatomic,assign) IBInspectable BOOL clearFloat;
@property(nonatomic, assign) IBInspectable CGFloat weight;
@end
来设置。 在默认情况下当我们建立的是一个左右浮动布局时,我们添加到布局里面的所有子视图默认都是向左浮动的,而当建立的是一个上下浮动布局时,我们添加到布局里面的所有子视图默认都是向上浮动的,因此当需要改动子视图浮动的方向则可以设置属性reverseFloat来实现,这个属性是一个BOOL类型的值,当设置为YES时表示按默认方向相反的方向浮动,也就是在左右浮动布局中,如果设置某个子视图的reverseFloat为YES的话则表示子视图是向右浮动,而对于上下浮动布局来数则表示是向下浮动。视图的扩展属性clearFloat也是一个BOOL类型,表示是否清除浮动,默认值是NO表示不清除浮动,当某个子视图需要有清除浮动的效果时,请将这个属性设置为YES。最后一个视图的扩展属性weight表示视图的宽度或者高度的比重,这个值默认值是0,表示不是按比重来指定宽度,这时候你在添加子视图时必须明确的指定宽度或者高度,而当设置为非0时则不需要为子视图指定宽度和高度,而由布局系统来自动帮你计算。这里的weight的设置范围是:0<=weight <=1.
上面分别的介绍了浮动布局的建立,以及子视图的扩展的属性设置来实现视图在浮动布局中的浮动方式、是否清除浮动、以及比重的设置方法。另外对于浮动布局来说,因为是从MyBaseLayout中派生的,因此浮动布局同样支持wrapContentWidth以及wrapContentHeight属性的设置的,也就是浮动布局的宽高可以由子视图来决定的,需要明确的是一般情况下我们对于左右浮动布局来说,只需要设置wrapContentHeight。当然你也可以设置wrapContentWidth(设置这个属性的前提是布局视图里面有一个子视图特别的宽);同样对于上下浮动布局来说,只需要设置wrapContentWidth。当然你也可以设置wrapContentHeight(设置这个属性的前提是布局视图里面有一个子视图特别的高)。
最后,我们看到浮动布局视图里面还有一个gravity属性,这个属性在左右浮动布局视图中可以用来设置所有子视图的整体的上,中,下三种停靠模式,而在上下浮动布局视图中则可以用来设置所有子视图的整体的左,中,右三种停靠模式。
下面的效果图就是我们使用浮动布局来实现的仿天猫和ZAKER界面布局的效果图:
浮动布局DEMO
上面的gif图片中有三个DEMO分别介绍浮动布局的,你可以通过DEMO中的FOLTest1ViewController来研究和学习浮动布局的各种属性的设置以及效果,而FOLTest2ViewController则是介绍的天猫首页的布局、FOLTest3ViewController介绍的则是ZAKER的卡片式布局的实现。通过DEMO我们可以看出,当我们要实现一些不规则的界面布局时,我们并不需要使用相对布局来实现,而只需设定正确的子视图的添加顺序,以及浮动属性的设置就能达到我们想要的效果,而且采用浮动布局的优点时不需要再去考虑视图之间的依赖关系的设置了。
为了说明智能边界线我们先来看这两个界面:
浮动布局11
上面的两个界面是仿淘宝和天猫首页以及ZAKER新闻的界面,我们来观察其中的每个区块之间的边界线。我们发现处在边缘部分是没有显示边界线的,而边界线只会显示在区块交界的地方显示一条边界线。在一般情况下,不规则边界线的显示我们有可能需要UI人员提供图片来完成,或者不提供图片我们在编程时也需要进行条件的判断以便决定是否需要在特定的位置绘制边界线,显然这样做将会增加我们的代码量。因此为了解决这个问题,我们的布局系统提供了边界线以及智能边界线的功能。如果您用了MyBaseLayout派生的6大布局的话,我们是可以通过基类提供的四个属性:
@property(nonatomic, strong) MyBorderLineDraw *leftBorderLine;
@property(nonatomic, strong) MyBorderLineDraw *rightBorderLine;
@property(nonatomic, strong) MyBorderLineDraw *topBorderLine;
@property(nonatomic, strong) MyBorderLineDraw *bottomBorderLine;
来为布局视图指定要显示的四边的边界线,我们可以支持设置边界线的颜色,粗细,缩进,以及点线等功能,这样我们就不再需要单独的提供边界线的切图了。要想看边界线的例子,可以查看LLTest4ViewController和AllTest3ViewController这两个DEMO的介绍。即便如此,对于上面的特殊情况,我们还需要进行编程以及条件判断来完成边界线的指定,因此为了解决这个问题,我们在布局中新增加了一个智能边界线的属性:
@property(nonatomic, strong) MyBorderLineDraw *IntelligentBorderLine;
@property(nonatomic, assign) BOOL notUseIntelligentBorderLine;
如果为某个布局视图设置了智能边界线的值,那么这个布局视图里面的子布局视图将会根据视图之间的关系而自动智能的生成边界线。这里需要强调的是只有布局视图里面的子布局视图才会生成智能的边界线,对于布局视图里面的非布局子视图是不会生成边界线的。而如果我们的某个布局视图里面的子布局视图不想使用智能的边界线,而是仍想自己手动设定,那么只需要将自己的notUseIntelligentBorderLine设置为YES即可,他表示不使用父布局提供的智能边界线功能。在当前的布局库版本中,我们只有线性布局、浮动布局、表格布局、流式布局支持智能边界线的设定,而框架布局、相对布局则是不支持的。正是因为布局系统里面提供的智能边界线的功能,就使得我们在设定布局视图之间的边界线时非常的简单,只需要一句话就能搞定。
上面就是我们要介绍的关于浮动布局的全部的东西,接下来我们将借着DEMO中的代码来具体的介绍我们如何使用浮动布局来实现上面的功能的。在介绍之前,我们这里说明一下,我们仍然是可以用子视图的扩展属性myLeftMargin,myRightMargin,myTopMargin,myBottomMargin这4个属性来指定视图之间的间距的。同时我们还支持子视图的宽度扩展属性widthDime的值可以设置为一个具体值,也可以等于布局视图的宽度,以及前面已经布好局的子视图的宽度,甚至还可以等于子视图的高度。
因为所有的关于浮动布局的代码我们都能在DEMO中找到,因为我们只介绍几个例子,其他的大家可以自己去研究,我们看下面的图:
浮动布局12
我们看到上面的界面左上角的区块的高度为180,而其余的区块都是90,并且每个区块的宽度都是屏幕的一半。为了容纳上面的界面我们需要先建立左右浮动的浮动布局:
CGFloat itemHeight = 90;
//品牌特卖
MyFloatLayout *layout1 = [MyFloatLayout floatLayoutWithOrientation:MyLayoutViewOrientation_Vert];
layout1.backgroundColor = [UIColor whiteColor];
layout1.wrapContentHeight = YES;
layout1.IntelligentBorderLine = [[MyBorderLineDraw alloc] initWithColor:[UIColor lightGrayColor]];
我们设定的layout1的高度由子视图决定,并且设置了智能边界线。接下来我们只需要每个区块按顺序依次添加进来即可。且从上面的区域中我们可以看出一共有3种不同的类型的区块分别是A,B, C三种区块,这三种区块其实是用MyFloatLayout来实现的。
A区块我们也可以用一个浮动布局来实现,我们只需要建立一个上下浮动布局,标题,小图都默认往上浮动。剩下的大图宽度和父布局宽度相等,并且设置weight=1就可以了,这部分代码的具体实现就在FOLTest2ViewController中的createItemLayout1_1的方法中实现。
B区块我们也可以用浮动布局来实现,我们只需要建立一个左右浮动布局,大图片优先向右浮动,高度和父布局高度相等,接下来主标题向左浮动,并且weight=1表示占用剩余的宽度;副标题也是向左浮动,并且设置清除浮动属性,同时设置weight=1表示占用剩余的宽度;最后的小图也是设置为左浮动,并且设置清除浮动属性。这部分代码的具体实现在FOLTest2ViewController中的createItemLayout1_3的方法中实现.
C区块我们也可以用浮动布局来实现,我们只需要建立一个左右浮动布局,主标题部分向左浮动,并且宽度和父布局宽度相等,付标题部分向左浮动,并且宽度和父布局宽度相等,而图片部分则向右浮动即可。
最后我们可以依次建立A,B,C三种区块然后依次的加入到layout1中去,加入时只需要设置A的高度为180,而宽度则是layout1的一半即可,而其他两种则高度设置为80,且宽度设置为layout1的一半即可。
浮动布局是一种功能非常强大的布局体系,从某种程度上来他甚至是相对布局的替代方案,而且要比相对布局要简单,因为里面的子视图之间是不需要设置约束和依赖关系的,单单凭借加入到布局视图的顺序,以及自身的宽高就能完成我们想要的功能。而且其提供的能力甚至要比CSS中的浮动属性更加强大。而我们在进行WEB前端开发时很多的界面布局其实都是通过CSS的浮动属性来完成的。因此我们也可以借助浮动布局来我们各种复杂的界面布局,而且浮动布局也能方便的实现线性布局以及流式布局的能力。如果您想了解更多的关于流式布局的功能请您访问我的github站点来了解更多: