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 不 ...
随机推荐
- [BZOJ5463][APIO2018]铁人两项:Tarjan+圆方树
分析 根据题目中的要求,从\(s\)出发前往\(f\)一定可以,并且只可能经过这两个结点所在的点双连通分量和它们之间的点双连通分量,因此切换点\(c\)只能从这些点中选取. 建出圆方树后,因为圆方树上 ...
- KafKa集群安装详细步骤
最近在使用Spring Cloud进行分布式微服务搭建,顺便对集成KafKa的方案做了一些总结,今天详细介绍一下KafKa集群安装过程: 1. 在根目录创建kafka文件夹(service1.serv ...
- oracle调整链接数
50用户以下:8GB 混用,oracle 占据1GB~3GB内存,open_cursors:300,processes:10050-100用户:16GB 混用,oracle 占据3~4GB内存,ope ...
- ES6注
1.Promise构造函数 //resolve(成功),reject(失败)两个参数 function runAsync(){ var p = new Promise(function(resolve ...
- Linux下用jar命令更新jar包文件
jar -uvf SDK_Web_ChartReport.war view/global/header.jsp echo '样式文件替换进包中' 查看jar包中的文件: jar -tvf SDK ...
- Spring+hibernate 配置实例
转自:http://www.cnblogs.com/hongten/archive/2012/03/10/java_spring_hibernate.html 项目结构: http://www.cnb ...
- java8 stream编程
说明:这是基于同事的培训材料做的练习,记录下来,以作日后自己coding分析和改进 1.准备 pom.xml <dependency> <groupId>org.apache. ...
- Spring Boot-配置
Spring 官方完整文档:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle Spring 官方配置文档:htt ...
- IntelliJ IDEA 配置 Hadoop 源码阅读环境
1.下载安装IDEA https://www.jetbrains.com/idea/download/#section=windows 2.下载hadoop源码 https://archive.apa ...
- CSS3——边框 圆角 背景 渐变 文本效果
边框 圆角边框 盒阴影 边界图片 圆角 CSS3 圆角制作器 指定每个角 背景 多重背景图像 大小 图像的定位 背景剪裁 渐变 线性渐变(Linear Gradients)- 向下/向上/向左/向右/ ...