節點容器
在容器中使用Nodes
AsyncDisplayKit有以下幾種 Container
ASDK Node Container | UIKit Equivalent |
---|---|
ASCollectionNode | 代替UIKit的 UICollectionView
|
ASPagerNode | 代替UIKit的 UIPageViewController
|
ASTableNode | 代替UIKit的 UITableView
|
ASViewController | 代替UIKit的 UIViewController
|
ASNavigationControllerv | 代替UIKit的 UINavigationController ,遵循ASVisibility 協議 |
ASTabBarController | 代替UIKit的 UITabBarController ,遵循ASVisibility 協議 |
Node Container的優勢
Node Container
可以自動地管理node
的智能預加載,它會保證node
的的布局計算、數據獲取、解碼和渲染會以異步的方式進行。
Node的子類
AsyncDisplayKit提供了以下幾種node
。
相對UIKit的組件來說 node
最大的改進就是將所有布局和顯示都放在子線程,因此主線程就能夠即時地響應各種事件。
ASDK Node | UIKit Equivalent |
---|---|
ASDisplayNode | 代替UIKit的 UIView ,其他的node都繼承于它 |
ASCellNode | 代替UIKit的 UITableViewCell 和 UICollectionViewCell ,用在 ASTableNode , ASCollectionNode 和 ASPagerNode 中 |
ASScrollNode | 代替UIKit的 UIScrollView ,這個 node 用在自定義滾動區域上非常有用 |
ASEditableTextNode | 代替UIKit的 UITextView
|
ASTextNode | 代替UIKit的 UILabel
|
ASImageNode | 代替UIKit的 UIImage
|
ASNetworkImageNode | |
ASMultiplexImageNode | |
ASVideoNode | 代替UIKit的 AVPlayerLayer
|
ASVideoPlayerNode | 代替UIKit的 UIMoviePlayer
|
SControlNode | 代替UIKit的 UIControl
|
ASButtonNode | 代替UIKit的 UIButton
|
ASMapNode | 代替UIKit的 MKMapView
|
AsyncDisplayKit 中的 node
相比UIKit中的組件更先進而且更方便。比如 ASNetworkImageNode
可以自動地加載和進行內存管理,而且還支持逐步加載Jpeg和動態gif圖片。
node
的層級結構如下
上圖中藍色高亮的node是對UIKit元素的封裝而成。比如 ASScrollNode
封裝自 UIScrollView
, ASCollectionNode
封裝自 UICollectionView
,ASMapNode
在實時地圖模式中就是 UIMapView
封裝。
基本重載方法
創建子類時,子類是
ASViewController
還是ASDisplayNode
有很大的區別。這感覺上是顯而易見的,但是有的區別是很微妙的,所有也需要特別注意。
ASDisplayNode
如果你使用的 node
組件類型于 UIView
的子控件,就必須注意下面幾條準則以確保你充分發揮了這個框架的潛力, node
也能很好的顯示。
-init
當使用 nodeBlock
的時候這個方法是在子線程進行的。但是,如何 -init
沒有運行完,其他方法就無法運行,所以這個方法永遠不要上鎖。
最重要的是你的 init
方法一定要能在任何隊列中調用。尤其是不要在初始化的時候初始化任何 UIKit
控件、點擊 node
的 view
或者 layer
或者添加任何手勢。這些事情應該放在 -didLoad
中。
-didLoad
這個方法在概念上類似于 UIViewController
的 -viewDidLoad
方法,它代表著后臺的 view
已經被加載完成了。要確保它是在主線程中執行的,在這個方法中很適合處理 UIKit
的各種操作(比如添加手勢,點擊 view
或者 layer
,初始化 UIKit
組件)。
-layout
在這個方法里調用 super
之后,布局規則對象會把所有的子節點都計算并且定位好,所以這個時間點是你手動進行布局所有子view的時機。或許更有用的是,有時候你想手動布局,但并不太容易創建一個布局規則對象,或者有時候你不想等所有子節點布局完畢,而只是很簡單的手動設置frame,如果是這樣的話,就在這個方法里寫。
layoutSpecThatFits
這個方法就是用來建立布局規則對象,產生 node
大小以及所有子 node
大小的地方,你創建的布局規則對象一直持續到這個方法返回的時間點,經過了這個時間點后,它就不可變了。尤其重要要記住的一點事,千萬不要緩存布局規則對象,當你以后需要他的時候,請重新創建。
ASViewController
ASViewController
是 UIViewController
的子類,包含了管理 node
的特性。因此它的所有方法一定要在主線程中使用。
-init
這個方法只調用一次,是在 ASViewController
的生命周期的最開始的時候調用。在它初始化的過程中,不要使用 self.view
或者 self.node.view
,它會強制 view
被提前創建。這些事情應該在 viewDidLoad
中完成。
ASViewController
的初始化方法是 initWithNode:
,代碼如下所示。一個 ASViewController
管理節點就像 UIViewController
管理 view
一樣,但是初始化的過程有小小的差異。
- (instancetype)init
{
_pagerNode = [[ASPagerNode alloc] init];
self = [super initWithNode:_pagerNode];
// setup any instance variables or properties here
if (self) {
_pagerNode.dataSource = self;
_pagerNode.delegate = self;
}
return self;
}
-loadView
建議不要使用這個方法,因為它相對于 viewDidLoad
來說沒有明顯的優勢反而有很多不足的地方。但如果你不去設置 self.view
的屬性就沒什么問題。調用 [super loadView]
它就會執行 node.view
。
-viewDidLoad
它會在 ASViewController
的生命周期的最開始調用,僅次于 -loadView
。這是你使用節點的 view
最早的時機。在這個方法里適合放只執行一次并且要使用 view/layer
的代碼,比如加手勢。
布局的代碼千萬不要放在這個方法里,因為界面發生改變也不會再調用這個方法重新布局。
-viewWillLayoutSubviews
這個方法調用的時機和節點 -layout
方法調用的時機一樣,它可以被執行很多次。只要它的節點被改變(比如旋轉,分屏,顯示鍵盤)或者繼承()都會立即被調用。