【iOS】AsyncDisplayKit的组件
节点容器
在容器中使用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 一样,但是初始化的过程有小小的差异。
1 | - (instancetype)init { |
-loadView
建议不要使用这个方法,因为它相对于 viewDidLoad 来说没有明显的优势反而有很多不足的地方。但如果你不去设置 self.view 的属性就没什么问题。调用 [super loadView] 它就会执行 node.view 。
-viewDidLoad
它会在 ASViewController 的生命周期的最开始调用,仅次于 -loadView 。这是你使用节点的 view 最早的时机。在这个方法里适合放只执行一次并且要使用 view/layer 的代码,比如加手势。
布局的代码千万不要放在这个方法里,因为界面发生改变也不会再调用这个方法重新布局。
-viewWillLayoutSubviews
这个方法调用的时机和节点 -layout 方法调用的时机一样,它可以被执行很多次。只要它的节点被改变(比如旋转,分屏,显示键盘)或者继承()都会立即被调用。






