前言
在學習別人文章的時候做一個記錄飘蚯,免得在需要的時候找不到。本文主要記錄原理性的內容福也,也會包含一些代碼局骤,具體使用請看文章。先把文章地址貼出來
這篇文章中的例子可以直接運行,另外的可以自己查看?AsyncDisplaykit2.0
安裝
項目使用CocoaPods安裝AsynDisplayKit,在Pod文件中輸入安裝
source 'https://github.com/CocoaPods/Specs.git'
target "AsyncDisplayKitForMit" do
pod 'AsyncDisplayKit'
end
使用介紹
在主線程中進行的一些大量操作包括:
計算大小和布局:包括 -heightForRowAtIndexPath: 或對 UILabel 上進行 -sizeThatFits 調用暴凑,以及大量的自動布局約束的解析峦甩。
圖片解碼:在一個 Image View 上使用 UIImage 就意味著要進行圖片數據的解碼。
繪圖:復雜文本以及手動繪制漸變色和陰影现喳。
對象生命周期:創(chuàng)建凯傲、操作和銷毀系統(tǒng)對象(比如創(chuàng)建一個 UIView)。
在正確使用的情況下嗦篱,AsynDisplayKit 默認允許你以異步方式操作所有的計算大小冰单、布局和繪圖操作。不需要進行任何其它的優(yōu)化灸促,App 就能夠大量減少需要在主線程上進行的工作诫欠。
ASDisplayNode 簡介
ASDisplayNode 是 ASDK 的核心類涵卵,甚至可以說是“心臟”,就像 MVC 中的 view荒叼,可以看做是另一種 UIView 或 CALayer轿偎。理解一個“節(jié)點”對象的最好方法是參考 UIView 和 CALayer 的關系,你對此應該很熟悉了被廓。
在一個 iOS App 中坏晦,屏幕上的每一個對象都表示了一個 CALayer 對象。UIView 私底下會創(chuàng)建和擁有一個 CALayer嫁乘,通過這個 CALayer 來感知觸摸或其他功能昆婿。UIView 自身并不是 CALayer 子類。相反亦渗,它包含了一個 CALayer 對象,并為它添加了一些功能汁尺。
這種概念也沿襲進了 ASDisplayNode:你可以認為它包含了一個 view法精,就好比 view 包含了一個 layer。
將節(jié)點通過一個普通的 View 放到表格上痴突,最終使它們能夠從后臺隊列中創(chuàng)建和配置搂蜓,默認情況下,它們會被異步渲染辽装。
幸運的是帮碰,這個 API 處理節(jié)點的方式和使用 UIView 或 CALayer 差不多。所有的 View 屬性都可以在節(jié)點類上找到相同的屬性拾积。你還可訪問底層的 view 或 layer——就像你可以通過 .layer 訪問 UIView 的 layer 一樣殉挽。
節(jié)點容器
要讓節(jié)點對象盡可能地提升性,必須將它和 4 個容器類協(xié)同工作拓巧。?
這 4 個容器類分別是:
ASViewController: 一個 UIViewController 子類斯碌,允許你創(chuàng)建節(jié)點并進行管理。
ASCollectionNode 和 ASTableNode: 對應于 UICollectionView 和 UITableView 的 Node 子類肛度,封裝了其底層細節(jié)傻唾。
ASPagerNode: 一個 ASCollectionNode 子類,封裝了掃動手勢承耿,對應于 UIKit 的 UIPageViewController冠骄。
這也太簡單了,但真正的秘密其實來自于 ASRangeController加袋,這 4 個類都會通過它來影響所包含的節(jié)點的行為×堇保現在,請聽我說职烧,暫且將那些內容保留到后面解釋蟀给。
使用
a:導入框架?#import <AsyncDisplayKit/AsyncDisplayKit.h>
b:聲明tabelNode屬性
@property (strong, nonatomic) ASTableNode *tableNode;
c:初始化容器,設置 TableNode 的數據和委托
和 UITableView 一樣蝙砌,ASTableNode 也使用了數據源和委托來獲得相關信息。Table Node 的 ASTableDataSource 和 ASTableDelegate 協(xié)議和 UITableViewDataSource 和 UITableViewDelegate 協(xié)議非常類似跋理。事實上择克,它們的方法定義都很像,比如 -tableNode:numberOfRowsInSection:前普。當然肚邢,這兩套協(xié)議也不是完全沒有區(qū)別,因為 ASTableNode 的行為和 UITableView 多少還是有一點不同拭卿。
?_tableNode = [[ASTableNode alloc]initWithStyle:UITableViewStylePlain];
? ?self.tableNode.dataSource = self;
? ?self.tableNode.delegate = self;
? ?self.tableNode.view.separatorStyle = UITableViewCellSeparatorStyleNone;
? ?[self.view addSubnode:self.tableNode];
d:然后骡湖,修改 -viewWillLayoutSubviews 方法:
- (void)viewWillLayoutSubviews {??
[superviewWillLayoutSubviews];
self.tableNode.frame = self.view.bounds;
}
到現在相當于創(chuàng)建好了tableview并設置好其frame,顯示cell需要再實現其數據源方法
e:遵守數據源相關協(xié)議
@interface AnimalTableController()<ASTableDataSource,ASTableDelegate>
f:實現兩個顯示前重要的協(xié)議
- (NSInteger)tableNode:(ASTableNode *)tableNode numberOfRowsInSection:(NSInteger)section { //返回多少行
? return self.animals.count;
}
然后峻厚,ASTableNodes 返回 cell 的方式和 UITableView 有所不同响蕴。將 -tableView:cellForRowAtIndexPath: 方法替換為:
?(ASCellNodeBlock)tableNode:(ASTableView *)tableView nodeBlockForRowAtIndexPath:(NSIndexPath*)indexPath {
RainforestCardInfo *animal ?= self.animals[indexPath.row];
ASCellNode *(^cellNodeBlock)() = ^ASCellNode *() {
? ? ? ? TableViewNodeCell *cellNode = [[TableViewNodeCell alloc] initWithHaiTao:haiTaoStyle];
? ? ? ? return cellNode;
? ? };
return cellNodeBlock;
}
代碼解釋如下:
TableViewNodeCell繼承自ASCellNode,一個 ASCellNode 等同于 UITableViewCell 或 UICollectionViewCell。尤其要注意這個方法返回的是一個 ASCellNodeBlock惠桃。因為一個 ASTableNode 在內部維護了所有的 cell浦夷,為每個 cell 的 Index Path 指定了一個塊,這樣當需要的時候就能夠異步地初始化所有 cell辜王。?
首先劈狐,你需要獲得一個數據模型對象,以便渲染這個 cell呐馆。這已經是固定的套路了肥缔。獲取數據,然后將它傳給后面的閉包汹来。IndexPath 在閉包中不需要续膳,這個例子中在閉包被調用之前數據就會先發(fā)生改變。
然后返回一個閉包收班,閉包中返回的類型必須是 ASCellNode姑宽。
不需要關心 cell 重用的問題,因此只需要實例化一個 cell闺阱。注意炮车,你返回的是一個 CardNode 而不是 CardCell。
這里有一點要注意酣溃。你可能也注意到了瘦穆,使用 ASDK 的時候 cell 不會進行重用。
g:相信你也知道了赊豌,在使用 UITableView 的時候通常都需要實現一個 -tableView:heightForRowAtIndexPath: 方法扛或。這是因為 UIKit 是通過這個委托方法來計算每個 cell 的高度的。
ASTableDelegate 中沒有 -tableView:heightForRowAtIndexPath: 方法碘饼。如果使用 ASDK, 所有的 ASCellNodes 都自己負責計算它們的大小熙兔。不需要提供一個固定的高度悲伶,你可以為每個 cell 指定一個最大尺寸和最小尺寸。這個例子中住涉,你需要讓每個 cell 至少占據屏幕 2/3 的高度麸锉。
現在我們暫時不討論這個,細節(jié)會在第二部分進行討論舆声。?
現在花沉,將 -tableView:heightForRowAtIndexPath: 方法替換為:
- (ASSizeRange)tableView:(ASTableView*)tableNode? constrainedSizeForRowAtIndexPath:(NSIndexPath*)indexPath {?
?CGFloat width = [UIScreen mainScreen].bounds.size.width; ?
CGSizemin= CGSizeMake(width, ([UIScreen mainScreen].bounds.size.height/3) *2);? CGSizemax= CGSizeMake(width, INFINITY);
returnASSizeRangeMake(min,max);
}
//剩下的重要內容就在自定義ASCellNode中了,包括里面的控件創(chuàng)建與布局。