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 不 ...
随机推荐
- xshell的快捷键
https://blog.csdn.net/hellozpc/article/details/46753575
- (65)CRC32校验C语言版本
#include<iostream> # include <stdio.h> # include <string.h> typedef unsigned int u ...
- JMS学习六(ActiveMQ消息传送模型)
ActiveMQ 支持两种截然不同的消息传送模型:PTP(即点对点模型)和Pub/Sub(即发布 /订阅模型),分别称作:PTP Domain 和Pub/Sub Domain. 一.PTP消息传送模型 ...
- [BZO3572][HNOI2014]世界树:虚树+倍增
分析 思维难度几乎为\(0\)的虚树码农(并不)题. 代码 #include <bits/stdc++.h> #define rin(i,a,b) for(register int i=( ...
- eclipse设置酷炫的代码颜色风格
eclipse安装默认的代码颜色风格是“白色背景”,颜色有些刺眼,于是想到手动去改eclipse的代码颜色,但改来改去还是很难达到我们的要求,甚至有时候将背景和某些代码的颜色改成相同,导致代码看不见. ...
- [LeetCode]-algorithms-Median of Two Sorted Arrays
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...
- 3、Shiro授权
Shiro授权过程和认证过程相似: 项目结构: package com.shiro.shiroframe; import org.apache.shiro.SecurityUtils; import ...
- 【python】集合 list差集|并集|交集
两个list差集 list(set(b).difference(set(a))) # b中有而a中没有的 示例: a=[1,2,3] b=[2,3] list(set(a).difference(se ...
- 前端必须掌握的 docker 技能(3)
概述 作为一个前端,我觉得必须要学会使用 docker 干下面几件事: 部署前端应用 部署 nginx 给部署的 nginx 加上 https 使用 docker compose 进行部署 给 ngi ...
- Python Module_oslo.vmware_连接 vCenter
目录 目录 前言 Install oslsvmware How to use the vSphere Web Service SDK 前言 oslo.vmware 是一个由 Python 实现的 vC ...