AsyncDisplayKit入门指南

转载 2015年11月20日 10:50:09


转: http://idlelife.org/archives/733


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风格)随机播放按钮。

1-shuffle-crop

我们的视图控制器代码将和下面的差不多:

- (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½个像素点高,离标准的44×44最小点击尺寸相距甚远,因此很难点击到。我们能够通过为 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--demo

  • 2015年06月14日 17:35
  • 5.73MB
  • 下载

AsyncDisplayKit 系列教程 —— 集成、示例

集成 集成 AsyncDisplayKit 非常简单,使用 CocoaPods 添加 pod "AsyncDisplayKit" 然后 pod update 就可以了。什么?你还不愿意使用 Co...

AsyncDisplayKit学习

前言AsyncDisplayKit是14年开源出来的库了,每一个库开发出来肯定都是为了解决某些问题的,所以藉着有任务在身就研究一下这个UI库的原理作为原始积累吧。60fps To keep its...
  • ouq68
  • ouq68
  • 2016年10月28日 01:18
  • 409

AsyncDisplayKit源代码解析-整体(一)

前言本文简书地址:http://www.jianshu.com/p/21f3d46b1bc5 本文的中文注释代码demo更新在我的github上。AsyncDisplayKit 是 Facebook...

Facebook开源《AsyncDisplayKit介绍》翻译

AsyncDisplayKit入门简介翻译

AsyncDisplayKit技术分析

Facebook前段时间发布了其iOS UI框架AsyncDisplayKit(ASDK)的1.0正式版,这个框架被用于Facebook自家的应用Paper,能够提高UI的流畅性并缩短响应时间。Asy...
  • xujim
  • xujim
  • 2015年01月23日 10:16
  • 444

Asyncdisplaykit

基本概念   AsyncDisplayKit的基本单元是node. ASDisplayNode是UIView和CALayer的抽象。ASDisplayNode是线程安全的,可以在工作线程中并行地...

用 AsyncDisplayKit 開發響應式 iOS App

原文:Using AsyncDisplayKit to Develop Responsive UIs in iOS 作者:ZIAD TAMIM 譯者:kmyhy 在 2011 年,我認識了...
  • kmyhy
  • kmyhy
  • 2017年02月12日 08:44
  • 1511

AsyncDisplayKit 2.0 Objective-C 教程

集成 AsyncDisplayKitAsyncDisplayKit 官方只支持 CocoaPods 和 Carthage 安装。Carthage 不用说了,它是 Swift 包管理器。以国内的网络状况...
  • kmyhy
  • kmyhy
  • 2017年02月18日 10:26
  • 2634

AsyncDisplayKit2.0教程(上)

原文:AsyncDisplayKit 2.0 Tutorial: Getting Started 作者: Luke Parham 译者:kmyhy “Art is anything you...
  • kmyhy
  • kmyhy
  • 2017年01月20日 17:18
  • 3123
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AsyncDisplayKit入门指南
举报原因:
原因补充:

(最多只允许输入30个字)