AsyncDisplayKit 復(fù)雜布局的界面流暢

piaotu1.png

最近學(xué)習(xí)AsyncDisplayKit的使用,現(xiàn)在將自己這幾天的學(xué)習(xí)的成果記錄一下,大家可以看一下,有什么不對(duì)的或者更好的方法大家也可以學(xué)習(xí)交流一下。AsyncDisplayKit的使用好處:在復(fù)雜布局的界面流暢絲毫不弱。(原理大家可以去看官方文檔 http://texturegroup.org/docs/getting-started.html

第一天

AsyncDisplayKit的使用在官網(wǎng)上有相關(guān)的技術(shù)文檔以及demo,自己可以邊學(xué)習(xí)邊看(網(wǎng)址:https://github.com/facebookarchive/AsyncDisplayKit)。第一天的第一步就是導(dǎo)入AsyncDisplayKit控件,我用的是cocoapod安裝的直接pod 'AsyncDisplayKit' 就可以啦,也可以將我項(xiàng)目中的文件發(fā)直接拖過去用(demo在后面)。下面是AsyncDisplayKit的控件以及布局

UIKit 節(jié)點(diǎn)容器
UICollectionView ASCollectionNode
UIPageViewController ASPagerNode
UITableView ASTableNode
UIViewController ASViewController
UINavigationController. ASNavigationControllerImplements the ASVisibility protocol.
UITabBarController ASTabBarController Implements the ASVisibility protocol
UIView ASDisplayNode
UITableViewCell & UICollectionViewCell ASCellNode
UIScrollView ASScrollNode
UITextView ASEditableTextNode
UILabel ASTextNode
UIImage ASImageNode, ASNetworkImageNode, ASMultiplexImageNode
AVPlayerLayer ASVideoNode
UIMoviePlayer ASVideoPlayerNode
UIButton ASButtonNode
MKMapView ASMapNode

ASLayoutSpec子類布局

布局 作用
ASWrapperLayoutSpec ASWrapperLayoutSpec是一個(gè)簡(jiǎn)單的ASLayoutSpec子類,可以ASLayoutElement根據(jù)布局元素上設(shè)置的大小來包裝和計(jì)算小孩的布局。ASWrapperLayoutSpec是輕松返回單個(gè)子節(jié)點(diǎn)的理想選擇-layoutSpecThatFits:??蛇x地,該子節(jié)點(diǎn)可以設(shè)置大小信息。但是,如果您需要設(shè)置除了大小的位置,請(qǐng)ASAbsoluteLayoutSpec改用。
ASStackLayoutSpec Texture中的所有l(wèi)ayoutSpecs中,ASStackLayoutSpec是最有用和最強(qiáng)大的。ASStackLayoutSpec使用flexbox算法來確定其子項(xiàng)的位置和大小。Flexbox旨在為不同的屏幕尺寸提供一致的布局。在堆疊布局中,您可以在垂直或水平堆疊中對(duì)齊項(xiàng)目。堆棧布局可以是另一個(gè)堆棧布局的子代,這使得可以使用堆棧布局規(guī)范創(chuàng)建幾乎任何布局。ASStackLayoutSpec除了其<ASLayoutElement>屬性,還有8個(gè)屬性:1.direction:指定孩子被堆疊的方向。如果設(shè)置了horizo??ntalAlignment和verticalAlignment,則它們將被再次解析,從而相應(yīng)地更新justifyContent和alignItems。2.spacing:每個(gè)子節(jié)點(diǎn)之間的空間量。3.horizontalAlignment:指定子節(jié)點(diǎn)如何水平對(duì)齊。取決于堆棧方向,設(shè)置對(duì)齊將導(dǎo)致justifyContent或alignItems被更新。未來方向改變后,對(duì)齊將保持有效。因此,優(yōu)選這些性質(zhì)。4.verticalAlignment:指定子節(jié)點(diǎn)如何垂直對(duì)齊。取決于堆棧方向,設(shè)置對(duì)齊將導(dǎo)致justifyContentalignItems被更新。未來方向改變后,對(duì)齊將保持有效。因此,優(yōu)選這些性質(zhì)。5.justifyContent:每個(gè)子節(jié)點(diǎn)之間的空間量。6.alignItems:子節(jié)點(diǎn)內(nèi)的橫貫方向。7.flexWrap:子節(jié)點(diǎn)是否被堆疊成單行或多行。默認(rèn)為單行。8.alignContent:如果有多條線,沿橫軸的線的方向。
ASInsetLayoutSpec ASInsetLayoutSpec將其傳遞constrainedSize.max CGSize給其子節(jié)點(diǎn),然后減去其插值。一旦子節(jié)點(diǎn)確定它的最終大小,插圖規(guī)格將其最終大小按照其子節(jié)點(diǎn)的大小加上其插入邊距。由于插圖布局規(guī)范的大小基于其子節(jié)點(diǎn)的大小,因此子節(jié)點(diǎn)必須具有內(nèi)在大小或明確設(shè)置其大小。
ASOverlayLayoutSpec 把它的子節(jié)點(diǎn)放在另一個(gè)組件上,作為疊加,覆蓋規(guī)格的大小是根據(jù)子節(jié)點(diǎn)的大小計(jì)算的,子節(jié)點(diǎn)必須具有固有的大小或設(shè)置的大小(子節(jié)點(diǎn)在下面)
ASBackgroundLayoutSpec 放置一個(gè)組件,將其后面的另一個(gè)組件作為背景展開。背景規(guī)格的大小根據(jù)子節(jié)點(diǎn)的大小計(jì)算,重要的是子節(jié)點(diǎn)必須具有固有的大小或設(shè)置的大小(子節(jié)點(diǎn)在上面)
ASCenterLayoutSpec ASCenterLayoutSpec其中心內(nèi)最大的子節(jié)點(diǎn)constrainedSize,ASCenterLayoutSpec 有兩個(gè)屬性:centeringOptions:確定子節(jié)點(diǎn)在中心規(guī)格中居中的方式。選項(xiàng)包括:None,X??,Y,XY。sizingOptions:確定中心規(guī)格將占用多少空間。選項(xiàng)包括:Default,最小X,最小Y,最小XY。
ASRatioLayoutSpec 可以擴(kuò)展的固定長(zhǎng)寬比布置組件。該規(guī)范必須有一個(gè)寬度或高度傳遞給它作為約束尺寸,因?yàn)樗褂么酥祦砜s放自身。
ASRelativeLayoutSpec 根據(jù)垂直和水平位置說明符,放置組件并將其放置在布局邊界內(nèi)。類似于“9部分”圖像區(qū)域,子節(jié)點(diǎn)可以位于四個(gè)角中的任何一個(gè),也可以位于四個(gè)邊中的任何一個(gè)以及中心。
ASAbsoluteLayoutSpec 在ASAbsoluteLayoutSpec您可以指定確切位置設(shè)定自己的(X / Y坐標(biāo))其子節(jié)點(diǎn)的layoutPosition
ASLayoutSpec 所有布局規(guī)范的子類的主類。主要工作是處理所有的子節(jié)點(diǎn)管理,但也可以用來創(chuàng)建自定義的布局規(guī)范。

第二天

今天我大概分析一下我的頁面布局,下圖就是我的頁面布局示意圖,整體是ASTableNode搭建,里面一條一條內(nèi)容我使用的是for循環(huán)創(chuàng)建ASDisPlayNode(綠色方框內(nèi)的),ASDisPlayNode中的圖片是ASCollectionNode創(chuàng)建的。綠色部分我剛開始用的是ASTableNode,開始使用ASTableView控件但是在后面的ASCollectionNode點(diǎn)擊事件不響應(yīng)(具體原因我還不知道,大家如果有知道可以告訴我一下?。?/p>

1.png

第三天

今天主要將頁面搭建完成,以及數(shù)據(jù)加載,里面涉及到布局以及控件使用大家可以查考AsyncDisplayKit官方文檔或者官方示例demo(如果官方示例demo不能運(yùn)行記得將工程pod install 一下就行了)。下面是我的布局代碼:


#import "OneCellNode.h"

@implementation OneCellNode
- (instancetype)initWithCommentItem:(OrderModel *)item indexPath:(NSIndexPath *)indexPath{
    if (self = [super init]) {
        self.index = indexPath;
        self.orderNodel = item;
        [self addDateNode];
        [self addTitleNode];
        [self addDescNode];
        [self addGoodNode];
    }
    return self;

}
- (void)addDateNode{
    self.dateNode = [[DateView alloc] initWithCommentItem:self.orderNodel.time date:self.orderNodel.date dateNum:self.orderNodel.dayCount];
    self.dateNode.backgroundColor = [UIColor whiteColor];
    [self addSubnode:self.dateNode];
}
- (void)addTitleNode{
    self.titleNode = [[ASTextNode alloc] init];
    self.titleNode.layerBacked = YES;
    self.titleNode.maximumNumberOfLines = 0;
    NSDictionary *attrs = @{ NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue" size:15.0f] ,NSForegroundColorAttributeName:UIColorFromRGB(0x444444)};
    self.titleNode.attributedText = [[NSAttributedString alloc]initWithString:self.orderNodel.title attributes:attrs];
    [self addSubnode:self.titleNode]; 
}
- (void)addDescNode{
    self.descNode = [[ASTextNode alloc] init];
    self.descNode.layerBacked = YES;
    self.descNode.maximumNumberOfLines = 0;
    NSDictionary *attrs = @{ NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue" size:15.0f] ,NSForegroundColorAttributeName:UIColorFromRGB(0x444444)};
    self.descNode.attributedText = [[NSAttributedString alloc]initWithString:self.orderNodel.desc attributes:attrs];
    [self addSubnode:self.descNode];  
}

- (void)addGoodNode{
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:self.orderNodel.goodArray.count];
   //遍歷循環(huán)創(chuàng)建每個(gè)商品條目
    for (int i = 0; i<self.orderNodel.goodArray.count; i++) {
                GoodImageView *node = [[GoodImageView alloc]initWithCommentItem:self.orderNodel.goodArray[i]];
                [self addSubnode:node];
                [array addObject:node];
            }
      _replayNodes = [array copy];
}
- (void)layout{
    [super layout];
    self.dateNode.frame = CGRectMake(0, 0, 130, self.frame.size.height);
}
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize{
    NSMutableArray *rightArray =[[NSMutableArray alloc] initWithObjects:_titleNode, _descNode,nil];
    [rightArray addObjectsFromArray:_replayNodes];
    ASStackLayoutSpec *rightStackLayout = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical spacing:8 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsStart children:rightArray];
    rightStackLayout.style.flexGrow = YES;
    rightStackLayout.style.flexShrink  = YES;
 //給dateNode節(jié)點(diǎn)一個(gè)寬度,高度可以隨意
    self.dateNode.style.preferredSize =  CGSizeMake(130 ,100);
    self.dateNode.style.flexShrink = YES;
    ASStackLayoutSpec *horStackLayout = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsStart children:@[self.dateNode,rightStackLayout]];
    horStackLayout.style.flexShrink = YES;
    return horStackLayout;
}

第四天

項(xiàng)目已經(jīng)完成了,功能也能實(shí)現(xiàn)了,但是關(guān)于縱向的紫色線條高度我一直沒有搞定,紫色線條是一個(gè)ASDisplayNode控件,在頁面中要設(shè)置他的高度否則不顯示,最后找了一個(gè)方法在layout方法中固定其寬高,代碼方法如下

- (void)layout{
    [super layout];
    self.dateNode.frame = CGRectMake(0, 0, 130, self.frame.size.height);
}

第五天

項(xiàng)目基本完成,將自己這幾天的開發(fā)過程記錄下來,來看一下效果

app.gif

demo:https://github.com/guofeifeifei/AsyncDisplayKitWuLiu
如果大家有好的方法也可以告訴我,我也會(huì)持續(xù)更新、時(shí)時(shí)在線,
在網(wǎng)上發(fā)現(xiàn)一個(gè)好的AsyncDisplayKit框架做的項(xiàng)目:https://github.com/12207480/LovePlayNews

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容