AsyncDisplayKit入门指南

作者: ch32053 | 来源:发表于2014-10-21 10:15 被阅读1054次

    Facebook前两天发布了其iOS UI框架AsyncDisplayKit(ASDK)1.0正式版,这个框架被用于Facebook自家的应用Paper中,能够提高UI的流畅性并缩短响应时间。

    下载和使用

    你可以使用CocoaPods来安装AsyncDisplayKit,在Podfile中添加:
    <pre><code>pod 'AsyncDisplayKit'</pre></code>
    OC中导入框架header,如果用Swift则可以创建Objective-C bridging header:
    <pre><code>#import <AsyncDisplayKit/AsyncDisplayKit.h></pre></code>

    概述

    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的实现差不多:
    <pre><code>_imageView = [[UIImageView alloc] init];
    _imageView.image = [UIImage imageNamed:@"hello"];
    _imageView.frame = CGRectMake(10.0f, 10.0f, 40.0f, 40.0f);
    [self.view addSubview:_imageView];</pre></code>
    我们能使用如下基于node的代码来替代它:
    <pre><code>_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];</pre></code>
    这并没有利用ASDK的异步调整大小和布局的功能,但已经有所改进了。第一段代码在主线程解码hello.png,第二段则在后台线程解码图像,并可能利用不同的CPU核心。
    (注意我们在node中设置了占位符的背景颜色,它会占据屏幕直到真正的内容出现。这种做法对于图像很好,但不太适用于文字——人们期望文字能直接展示,图片则允许有加载延迟。我们后面会讨论如何改进的技术。)

    node按钮

    ASImageNode和ASTextNode都继承了ASControlNode,所以你能将它们当做按钮使用。假设我们在开发音乐播放器,并且希望添加(非拟物化的,iOS 7风格)随机播放按钮。



    我们的视图控制器代码将和下面的差不多:
    <pre><code>- (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!");
      }</pre></code>
      这段代码能正常工作。不幸的是,这个按钮只有14.5个像素点高,离标准的44x44最小点击尺寸相距甚远,因此很难点击到。我们能够通过为 text node创建子类,并且覆盖-hitTest:withEvent:来解决这个问题。我们甚至能强制text view在布局中的最低高度,但如果有更优雅的解决办法不是更好吗?
      <pre><code>// 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);</pre></code>
      就是这样!Hit-test slops在所有node中都能正常工作,并且是一个展示这个新的抽象层能干什么的极好的示例。

    后面还会讲如何自定义node、异步的工作方式、最大限度的利用AsyncDisplayKit等,感兴趣的可以查看官方文档
    转载自:http://www.cocoachina.com/ios/20141020/9975.html

    相关文章

      网友评论

        本文标题:AsyncDisplayKit入门指南

        本文链接:https://www.haomeiwen.com/subject/fvxmtttx.html