Layout 布局
?ASDK有一套自己的成熟的的布局方案牲览,最大的好處是提升性能诵原,這套布局主要借鑒了CSS的FlexBox思想,在布局的時候我們要注意一個原則:
?從里往外!
- flex有2個很重要的概念:主軸和交叉軸案淋。主軸是子視圖默認的排列方向矢腻,交叉軸是和主軸相垂直的軸煌张,是項目在交叉方向上的排列方式早歇。主軸默認是水平的焰檩,可以修改為豎直方向憔涉。
layout-1.png
- 在自定義的
displaynode
類中重寫- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
方法,進行布局析苫。如果沒有自定義node兜叨,官方提供了一個layoutSpecBlock
同樣可以實現(xiàn)布局。
// 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
- 這兩種布局方式比較類似
- 背景布局:把一個視圖拉伸作為另外一個視圖的背景
- 覆蓋布局:和背景布局是對立的
比較常見的業(yè)務場景:組合兩個視圖
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
- 根據(jù)自身的高度或者寬度來設置自身比例(高度 : 寬度),所以必須先設置自身的高度或者寬度雳灾。 (ratio > 1 == 高>寬漠酿,ratio < 1 == 高<寬)
常見的業(yè)務場景:圖片設置比例等
layout-2.png
ASRelativeLayoutSpec
- 可以設置類似九宮格上任意一個區(qū)域的位置,需要水平和豎直方向組合使用:
-
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
:?這個中心布局會占據(jù)多少空間(minimum X, minimum Y, minimum XY)
-
layout-3.png
ASCenterLayoutSpec *centerLayoutSpec = [ASCenterLayoutSpec
centerLayoutSpecWithCenteringOptions:ASCenterLayoutSpecCenteringXY
sizingOptions:ASCenterLayoutSpecSizingOptionDefault child:self.subNode];
ASWrapperLayoutSpec
- 根據(jù)布局視圖上設置的大小來包裝和計算子視圖的布局。
ASCornerLayoutSpec
- 常見的業(yè)務場景:設置角標
layout-4.png
// 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的優(yōu)先級高份帐。 -
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;