AsyncDisplayKit
Facebook发布了其iOS UI框架AsyncDisplayKit(ASDK)1.0正式版,这个框架被用于Facebook自家的应用Paper中,能够提高UI的流畅性并缩短响应时间。
下载和使用
你可以使用CocoaPods来安装AsyncDisplayKit,在Podfile中添加:
pod 'AsyncDisplayKit'
OC中导入框架header,如果用Swift则可以创建Objective-C bridging header:
#import <AsyncDisplayKit/AsyncDisplayKit.h>
概述
AsyncDisplayKit(ASDK)的基本单元是node,ASDisplayNode是UIView之上的抽象层,同时也是CALayer的抽象层。和只能被用在主线程的视图不同,nodes是线程安全的:你能并行的实例化并设置整个node层级,并且在后台线程里运行。
为了保证它的用户界面的流畅性和响应性,你的app渲染帧率应该和iOS基准保持同步,即60帧每秒。这意味着主线程对每一帧有60分之一的时间来推送,也就是说大约要在16毫秒内执行所有的布局和绘制代码。而由于系统的性能开销,在导致丢帧之前,你的代码通常只有不到10毫秒的时间来执行。
AsyncDisplayKit让你将图像解码、调整文字大小并渲染,以及其他高耗时的UI操作移出主线程。当然它还有其他的一些功能,你可以在官方文档中探索。
作为视图直接替代的Node
如果你之前处理过视图,那么你已经知道如何使用node了。Node的API也类似于UIView,不过更方便。比如,你能直接读取公共的CALayer属性。如果想添加一个node到现有的视图或层级,使用node.view或node.layer。
AsyncDisplayKit包括一些强力的组件:
· ASDisplayNode. UIView的副本 —一个子类,用来自定义node。
· ASControlNode. 类似于UIControl —用来制作按钮的子类。
· ASImageNode. 类似于UIImageView —异步的解码图像资源。
· ASTextNode. 类似于UITextView — 基于TextKit构建,支持富文本的全部特性。
· ASTableView. UITableView子类,用于支持node。
你可以将这些用作UIKit副本的直接替代。即便ASDK在完整的基于node的层级下工作十分高效,使用node替代独立视图能够更加的提高性能。
让我们来看一个例子。
我们一开始在主线程中异步的使用node——和你平常使用视图的方式一样。我们的代码和自定义视图控制器-loadView的实现差不多:
_imageView = [[UIImageView alloc] init]; _imageView.image = [UIImage imageNamed:@"hello"]; _imageView.frame = CGRectMake(10.0f, 10.0f, 40.0f, 40.0f); [self.view addSubview:_imageView];
我们能使用如下基于node的代码来替代它:
_imageNode = [[ASImageNode alloc] init]; _imageNode.backgroundColor = [UIColor lightGrayColor]; _imageNode.image = [UIImage imageNamed:@"hello"]; _imageNode.frame = CGRectMake(10.0f, 10.0f, 40.0f, 40.0f); [self.view addSubview:_imageNode.view];
这并没有利用ASDK的异步调整大小和布局的功能,但已经有所改进了。第一段代码在主线程解码hello.png,第二段则在后台线程解码图像,并可能利用不同的CPU核心。
(注意我们在node中设置了占位符的背景颜色,它会占据屏幕直到真正的内容出现。这种做法对于图像很好,但不太适用于文字——人们期望文字能直接展示,图片则允许有加载延迟。我们后面会讨论如何改进的技术。)
node按钮
ASImageNode和ASTextNode都继承了ASControlNode,所以你能将它们当做按钮使用。假设我们在开发音乐播放器,并且希望添加(非拟物化的,iOS 7风格)随机播放按钮。

我们的视图控制器代码将和下面的差不多:
- (void)viewDidLoad { [super viewDidLoad]; // attribute a string NSDictionary *attrs = @{ NSFontAttributeName: [UIFont systemFontOfSize:12.0f], NSForegroundColorAttributeName: [UIColor redColor], }; NSAttributedString *string = [[NSAttributedString alloc] initWithString:@"shuffle" attributes:attrs]; // create the node _shuffleNode = [[ASTextNode alloc] init]; _shuffleNode.attributedString = string; // configure the button _shuffleNode.userInteractionEnabled = YES; // opt into touch handling [_shuffleNode addTarget:self action:@selector(buttonTapped:) forControlEvents:ASControlNodeEventTouchUpInside]; // size all the things CGRect b = self.view.bounds; // convenience CGSize size = [_shuffleNode measure:CGSizeMake(b.size.width, FLT_MAX)]; CGPoint origin = CGPointMake(roundf( (b.size.width - size.width) / 2.0f ), roundf( (b.size.height - size.height) / 2.0f )); _shuffleNode.frame = (CGRect){ origin, size }; // add to our view [self.view addSubview:_shuffleNode.view]; } - (void)buttonTapped:(id)sender { NSLog(@"tapped!"); }
这段代码能正常工作。不幸的是,这个按钮只有14.5个像素点高,离标准的44x44最小点击尺寸相距甚远,因此很难点击到。我们能够通过为 text node创建子类,并且覆盖-hitTest:withEvent:来解决这个问题。我们甚至能强制text view在布局中的最低高度,但如果有更优雅的解决办法不是更好吗?
// size all the things /* ... */ // make the tap target taller CGFloat extendY = roundf( (44.0f - size.height) / 2.0f ); _shuffleNode.hitTestSlop = UIEdgeInsetsMake(-extendY, 0.0f, -extendY, 0.0f);
就是这样!Hit-test slops在所有node中都能正常工作,并且是一个展示这个新的抽象层能干什么的极好的示例。
后面还会讲如何自定义node、异步的工作方式、最大限度的利用AsyncDisplayKit等,感兴趣的可以查看官方文档。
AsyncDisplayKit的更多相关文章
- [转]AsyncDisplayKit 教程:达到 60 FPS 的滚动帧率
[原文:https://github.com/nixzhu/dev-blog/blob/master/2014-11-22-asyncdisplaykit-tutorial-achieving-60- ...
- [翻译] AsyncDisplayKit
AsyncDisplayKit AsyncDisplayKit is an iOS framework that keeps even the most complex user interfaces ...
- AsyncDisplayKit技术分析
转载请注明出处:http://xujim.github.io/ios/2014/12/07/AsyncDisplayKit_inside.html ,谢谢 前言 Facebook前段时间发布了其iOS ...
- 分析facebook的AsyncDisplayKit框架,async-display使用async-transaction
上一篇<分析facebook的AsyncDisplayKit框架中的Transaction的工作原理>介绍了fb的asdk的异步事务ASAsyncTransaction,本篇介绍其在asd ...
- 分析facebook的AsyncDisplayKit框架中的Transaction的工作原理
在AsyncDisplayKit框架中有一个_ASAsyncTransaction模块,用于AsyncDiplayNode的异步事务,使用了dispatch_group实现. 主要目的是将operat ...
- AsyncDisplayKit编译和使用注意事项
Facebook开源框架,在github上可下载到.首先要编译AsyncDisplayKit库项目,有可能会出现下面错误: cocoaPods是基于ruby的项目版本控制软件,如果是ruby新手就会不 ...
- UML分析AsyncDisplayKit框架-ASMuplexImageNode异步下载时序图。
PS:博客园图片服务器不正常工作,数据上传后服务器返回http500,园方迟迟还没解决. 我从2016-01-18 05:52向园方反馈问题-请问博客园的图片服务器有在正常运行吗,至此时2016-01 ...
- iOS开发之多种Cell高度自适应实现方案的UI流畅度分析
本篇博客的主题是关于UI操作流畅度优化的一篇博客,我们以TableView中填充多个根据内容自适应高度的Cell来作为本篇博客的使用场景.当然Cell高度的自适应网上的解决方案是铺天盖地呢,今天我们的 ...
- 【转】GitHub 排名前 100 的安卓、iOS项目简介
GitHub Android Libraries Top 100 简介 排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果, 然后过滤了跟 Android 不 ...
随机推荐
- 【Mark】博弈类题目小结(HDU,POJ,ZOJ)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 首先当然要献上一些非常好的学习资料: 基础博弈的小 ...
- JAVA周二学习总结
第一周我感觉我学到了不少东西,其中有上学期C语言学的不好的原因,因为不想再挂科就有认真的在听. 学到的东西有JAVA的基本书写模式自己懂了,还在课堂上弄会了交换数据的方法,还有运算的算法,另外还有数据 ...
- Maven中的dependency详解
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> & ...
- WINDOWS API 大全(二)
9. API之设备场景函数 CombineRgn 将两个区域组合为一个新区域CombineTransform 驱动世界转换.它相当于依顺序进行两次转换CreateCompatibleDC 创建一个与特 ...
- vundle就是vim bundle的插件管理成ide
如何配置一个高效的php编辑环境, 很好 对vundle的操作, 除了仓库名称是vundle.git (*.git就是仓库) 和 本地目录名是 vundle之外, 其他的操作都是bundle git ...
- 2017-0ctf-babyheap
fastbin attack + unsortedbin attack + __malloc_hook 的基础利用 题目下载 : https://uaf.io/assets/0ctfbabyheap ...
- Java多线程学习——wait方法(管道法/生产者消费者模式)
简单介绍管道法: 生产者生产数据输送到管道,消费者从管道拿出数据,管道为空消费者等待,管道满生产者生产,消费者消费生产者生产,生产者生产消费者消费. public class Corn { //要生产 ...
- 使用Inception-v3进行图像分类
https://blog.csdn.net/sinat_27382047/article/details/80534234 https://www.jianshu.com/p/cc830a6ed54b ...
- iview报错[Vue warn]: Error in render: "TypeError: ctx.injections.tableRoot.$scopedSlots[ctx.props.column.slot] is not a function"
原因是我使用了iview的<Table>组件,我给Table组件的columns中定义了4个含有slot的列,但是实际在<Table>中只使用了其中3个,导致的报错. 也就是说 ...
- Windows上Tomcat安装以及解决乱码问题
Windows上Tomcat安装以及解决乱码问题 下载tomcat8 1.进入tomcat官网 官方网站 2.选择windows的版本 解压 确定自己配置好了jdk jdk的相关配置 配置好tomca ...