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

piaotu1.png

最近學(xué)習(xí)AsyncDisplayKit的使用,現(xiàn)在將自己這幾天的學(xué)習(xí)的成果記錄一下,大家可以看一下,有什么不對的或者更好的方法大家也可以學(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' 就可以啦,也可以將我項目中的文件發(fā)直接拖過去用(demo在后面)。下面是AsyncDisplayKit的控件以及布局

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

第二天

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

1.png

第三天

今天主要將頁面搭建完成,以及數(shù)據(jù)加載,里面涉及到布局以及控件使用大家可以查考AsyncDisplayKit官方文檔或者官方示例demo(如果官方示例demo不能運行記得將工程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)建每個商品條目
    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é)點一個寬度,高度可以隨意
    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;
}

第四天

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

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

第五天

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

app.gif

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

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

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