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等,感興趣的可以查看官方文檔。
轉載于:https://www.cnblogs.com/W-Kr/p/5191435.html
總結
以上是生活随笔為你收集整理的AsyncDisplayKit的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++计算几何库
- 下一篇: [转]SpringMVC+Hiberna