Layout 布局
ASDK有一套自己的成熟的的布局方案,最大的好处是提升性能,这套布局主要借鉴了CSS的FlexBox思想,在布局的时候我们要注意一个原则:
从里往外!
- flex有2个很重要的概念:主轴和交叉轴。主轴是子视图默认的排列方向,交叉轴是和主轴相垂直的轴,是项目在交叉方向上的排列方式。主轴默认是水平的,可以修改为竖直方向。
layout-1.png
- 在自定义的
displaynode
类中重写- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
方法,进行布局。如果没有自定义node,官方提供了一个layoutSpecBlock
同样可以实现布局。
// 1.自定义node
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize{
请在这里进行布局
、、、
}
// 2.没有自定义node
self.node.layoutSpecBlock = ^ASLayoutSpec *(ASDisplayNode *node, ASSizeRange constrainedSize) {
请在这里进行布局
、、、
};
相关API继承关系
-
ASLayoutSpec
-
ASStackLayoutSpec
: 栈布局 -
ASAbsoluteLayoutSpec
: 绝对布局 -
ASBackgroundLayoutSpec
: 背景布局 -
ASOverlayLayoutSpec
: 覆盖布局 -
ASInsetLayoutSpec
: 边距布局 -
ASRatioLayoutSpec
: 比例布局 -
ASRelativeLayoutSpec
: 相对布局 -
ASCenterLayoutSpec
: 居中布局 -
ASWrapperLayoutSpec
: 填充布局 -
ASCornerLayoutSpec
: 圆角布局
-
ASStackLayoutSpec
ASStackLayoutSpec是比较常用的spec,包含几个常见的属性:
-
direction
: 主轴的方向-
ASStackLayoutDirectionHorizontal
: 水平 -
ASStackLayoutDirectionVertical
: 竖直
-
-
spacing
: 主轴上子视图的之间的间距 -
justifyContent
: 子视图在主轴上的排列方式(下面默认主轴为水平)-
ASStackLayoutJustifyContentStart
: 从左往右排列 -
ASStackLayoutJustifyContentCenter
: 居中排列 -
ASStackLayoutJustifyContentEnd
: 从后往前排列 -
ASStackLayoutJustifyContentSpaceBetween
: 间隔排列,两端没有间隙 -
ASStackLayoutJustifyContentSpaceAround
: 间隔排列,两端有间隙(每个子视图的两端距离是相等的,所以如果有超过3个视图,那么中间的视图的间距比两端的视图大一倍)
-
-
alignItems
: 交叉轴排列方式-
ASStackLayoutAlignItemsStart
: 起点对齐 -
ASStackLayoutAlignItemsEnd
: 终点对齐 -
ASStackLayoutAlignItemsCenter
: 居中对齐 -
ASStackLayoutAlignItemsStretch
: 没有设置高度前提下,会去拉伸直到填满整个父视图 -
ASStackLayoutAlignItemsBaselineFirst
: (水平布局专有)第一个子视图的文字内容作为基线对齐 -
ASStackLayoutAlignItemsBaselineLast
: (水平布局专有)最后一个子视图的文字内容作为基线对齐
-
-
children
: 添加约束的子视图 (注意:添加顺序不同,布局顺序不同e.g.[view1,view2] 和[view2,view1]这两种布局会不同)
ASAbsoluteLayoutSpec
- 可以设置视图的绝对位置,但是这个比较固定,官方文档里不建议使用
ASAbsoluteLayoutSpec *absoluteLayoutSpec = [ASAbsoluteLayoutSpec absoluteLayoutSpecWithChildren:@[self.photoNode,
self.iconNode]];
return absoluteLayoutSpec;
ASBackgroundLayoutSpec && ASOverlayLayoutSpec
- 这两种布局方式比较类似
- 背景布局:把一个视图拉伸作为另外一个视图的背景
- 覆盖布局:和背景布局是对立的
比较常见的业务场景:组合两个视图
ASBackgroundLayoutSpec *backgroundLayoutSpec = [ASBackgroundLayoutSpec backgroundLayoutSpecWithChild:self.blueNode
background:self.redNode];
// child:是在下面的视图,overlay是设置在上层的视图
ASOverlayLayoutSpec *overlayLayoutSpec = [ASOverlayLayoutSpec overlayLayoutSpecWithChild:self.redNode overlay:self.blueNode];
ASInsetLayoutSpec
- 可以设置边距,需要设置一个
UIEdgeInsets
ASInsetLayoutSpec *insetLayoutSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsMake(30, 30, 30, 30)
child:self.cyanNode];
ASRatioLayoutSpec
- 根据自身的高度或者宽度来设置自身比例(高度 : 宽度),所以必须先设置自身的高度或者宽度。 (ratio > 1 == 高>宽,ratio < 1 == 高<宽)
常见的业务场景:图片设置比例等
ASRelativeLayoutSpec
- 可以设置类似九宫格上任意一个区域的位置,需要水平和竖直方向组合使用:
-
horizontalPosition
: 水平方向位置-
ASRelativeLayoutSpecPositionStart
: 左边 -
ASRelativeLayoutSpecPositionCenter
: 中间 -
ASRelativeLayoutSpecPositionEnd
: 右边
-
-
verticalPosition
: 竖直方向位置-
ASRelativeLayoutSpecPositionStart
: 上边 -
ASRelativeLayoutSpecPositionCenter
: 中间 -
ASRelativeLayoutSpecPositionEnd
: 下边
-
-
self.subNode.style.preferredSize = CGSizeMake(100, 100);
ASRelativeLayoutSpec *relativeLayoutSpec = [ASRelativeLayoutSpec
relativePositionLayoutSpecWithHorizontalPosition:ASRelativeLayoutSpecPositionEnd
verticalPosition:ASRelativeLayoutSpecPositionCenter
sizingOption:ASRelativeLayoutSpecSizingOptionDefault child:self.subNode];
return relativeLayoutSpec;
ASCenterLayoutSpec
- 设置主轴或者交叉轴上的居中布局
-
centeringOptions
: 居中方式(X,Y,XY轴) -
sizingOptions
: 这个中心布局会占据多少空间(minimum X, minimum Y, minimum XY)
-
ASCenterLayoutSpec *centerLayoutSpec = [ASCenterLayoutSpec
centerLayoutSpecWithCenteringOptions:ASCenterLayoutSpecCenteringXY
sizingOptions:ASCenterLayoutSpecSizingOptionDefault child:self.subNode];
ASWrapperLayoutSpec
- 根据布局视图上设置的大小来包装和计算子视图的布局。
ASCornerLayoutSpec
- 常见的业务场景:设置角标
// corner:边角上的node
// location: corner的位置可以设置为
/*
ASCornerLayoutLocationTopLeft, 左上
ASCornerLayoutLocationTopRight, 右上
ASCornerLayoutLocationBottomLeft, 左下
ASCornerLayoutLocationBottomRight, 右下
*/
ASCornerLayoutSpec *cornerLayoutSpec = [ASCornerLayoutSpec cornerLayoutSpecWithChild:self.photoNode corner:self.dotNode
location:ASCornerLayoutLocationTopRight];
// offset:corner的偏移量
cornerLayoutSpec.offset = CGPointMake(-3, 3);
self.photoNode.style.preferredSize = CGSizeMake(100, 100);
self.dotNode.style.preferredSize = CGSizeMake(10, 10);
return cornerLayoutSpec;
layout 元素的属性
-
ASStackLayoutElement
-
spacingBefore
: 栈布局中,第一个子视图在主轴上的间隙 -
spacingAfter
: 栈布局中,最后一个子视图在主轴上的间隙 -
flexGrow
: 定义子视图的放大比例,如果为0,即使有剩余空间也不会放大。如果所有子视图都设置,那么就按照设置的比例分配,如果都设置为1,那么是均分剩余空间,如果有一个设置为2,那么该视图分到的空间将是其他视图的2倍 -
flexShrink
: 缩小比例:当空间不足的时候,缩小子视图,如果所有的子视图都设置为1就是等比例缩小,如果有一个子视图设置为0,表示该视图不缩小。 -
flexBasis
: 可以指定某个约束的初始大小 -
alignSelf
:这个属性和alignItems效果一样,设置了这个,那么就会覆盖alignItems的效果 -
ascender
:在baseline选项中生效,文字基准线的顶部距离 -
descender
:在baseline选项中生效,文字基准线的底部距离
-
-
ASAbsoluteLayoutElement
-
layoutPosition
:ASAbsoluteLayoutSpec布局中,设置的起点位置
-
-
ASLayoutElement
-
width
:设置ASLayoutElement的内容宽度,默认ASDimensionAuto。minWidth和maxWidth会覆盖width。 -
height
:设置spec的内容高度 -
minWidth
:设置spec最小宽度 -
maxWidth
:设置spec最大宽度 -
minHeight
:设置spec最小高度 -
maxHeight
:设置spec最大高度 -
preferredSize
: 设置视图的大小,但是如果设置了maxSize或者minSize,那么maxsize和minSize的优先级高。 -
minSize
:设置最小尺寸 -
maxSize
:设置最大尺寸 -
preferredLayoutSize
:设置建议的相对尺寸,也就是一般推荐写百分比 -
minLayoutSize
:设置最小的相对尺寸 -
maxLayoutSize
:设置最大的相对尺寸
-
-
size
-
ASDimension
:本质上就是CGFloat,可以表示具体的值也可以表示百分比。
// dimension returned is relative (%) ASDimensionMake(@"50%"); ASDimensionMakeWithFraction(0.5); // dimension returned in points ASDimensionMake(@"70pt"); ASDimensionMake(70); ASDimensionMakeWithPoints(70);
-
ASLayoutSize
:类似CGSize,不同点是width和height既可以代表点的值也可以代表百分比的值-
ASSizeRange
:表示CGSize对(最小size和最大size)
-
// constrainedSize:表示一个自定义的node里的子元素可以设置的最大和最小的size
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize;
网友评论