Overall improvements for the SocialAppLayout example

This commit is contained in:
Michael Schneider 2016-02-24 20:18:20 -08:00
parent 8418d8be24
commit 7dd2fbfad1
9 changed files with 148 additions and 204 deletions

View File

@ -11,14 +11,7 @@
#import <AsyncDisplayKit/AsyncDisplayKit.h> #import <AsyncDisplayKit/AsyncDisplayKit.h>
@interface CommentsNode : ASControlNode { @interface CommentsNode : ASControlNode
ASImageNode *_iconNode;
ASTextNode *_countNode;
NSInteger _comentsCount;
}
- (instancetype)initWithCommentsCount:(NSInteger)comentsCount; - (instancetype)initWithCommentsCount:(NSInteger)comentsCount;

View File

@ -12,32 +12,32 @@
#import "CommentsNode.h" #import "CommentsNode.h"
#import "TextStyles.h" #import "TextStyles.h"
@interface CommentsNode ()
@property (nonatomic, strong) ASImageNode *iconNode;
@property (nonatomic, strong) ASTextNode *countNode;
@property (nonatomic, assign) NSInteger commentsCount;
@end
@implementation CommentsNode @implementation CommentsNode
- (instancetype)initWithCommentsCount:(NSInteger)comentsCount { - (instancetype)initWithCommentsCount:(NSInteger)comentsCount {
self = [super init]; self = [super init];
if (self) {
if(self) { _commentsCount = comentsCount;
_comentsCount = comentsCount;
_iconNode = [[ASImageNode alloc] init]; _iconNode = [[ASImageNode alloc] init];
_iconNode.image = [UIImage imageNamed:@"icon_comment.png"]; _iconNode.image = [UIImage imageNamed:@"icon_comment.png"];
[self addSubnode:_iconNode]; [self addSubnode:_iconNode];
_countNode = [[ASTextNode alloc] init]; _countNode = [[ASTextNode alloc] init];
if(_comentsCount > 0) { if (_commentsCount > 0) {
_countNode.attributedString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%zd", _commentsCount] attributes:[TextStyles cellControlStyle]];
_countNode.attributedString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%ld", (long)_comentsCount] attributes:[TextStyles cellControlStyle]];
} }
[self addSubnode:_countNode]; [self addSubnode:_countNode];
// make it tappable easily // make it tappable easily
self.hitTestSlop = UIEdgeInsetsMake(-10, -10, -10, -10); self.hitTestSlop = UIEdgeInsetsMake(-10, -10, -10, -10);
} }
return self; return self;
@ -46,18 +46,13 @@
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize { - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize {
ASStackLayoutSpec *mainStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:6.0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsCenter children:@[_iconNode, _countNode]]; ASStackLayoutSpec *mainStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:6.0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsCenter children:@[self.iconNode, self.countNode]];
// set sizeRange to make width fixed to 60 // set sizeRange to make width fixed to 60
mainStack.sizeRange = ASRelativeSizeRangeMake(ASRelativeSizeMake( ASRelativeSize min = ASRelativeSizeMake(ASRelativeDimensionMakeWithPoints(60.0), ASRelativeDimensionMakeWithPoints(0.0));
ASRelativeDimensionMakeWithPoints(60.0), ASRelativeSize max = ASRelativeSizeMake(ASRelativeDimensionMakeWithPoints(60.0), ASRelativeDimensionMakeWithPoints(40.0));
ASRelativeDimensionMakeWithPoints(0.0) mainStack.sizeRange = ASRelativeSizeRangeMake(min,max);
), ASRelativeSizeMake(
ASRelativeDimensionMakeWithPoints(60.0),
ASRelativeDimensionMakeWithPoints(40.0)
));
return [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[mainStack]]; return [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[mainStack]];
} }

View File

@ -11,18 +11,8 @@
#import <AsyncDisplayKit/AsyncDisplayKit.h> #import <AsyncDisplayKit/AsyncDisplayKit.h>
@interface LikesNode : ASControlNode { @interface LikesNode : ASControlNode
ASImageNode *_iconNode;
ASTextNode *_countNode;
NSInteger _likesCount;
BOOL _liked;
}
- (instancetype)initWithLikesCount:(NSInteger)likesCount; - (instancetype)initWithLikesCount:(NSInteger)likesCount;
+ (BOOL) getYesOrNo;
@end @end

View File

@ -12,14 +12,19 @@
#import "LikesNode.h" #import "LikesNode.h"
#import "TextStyles.h" #import "TextStyles.h"
@interface LikesNode ()
@property (nonatomic, strong) ASImageNode *iconNode;
@property (nonatomic, strong) ASTextNode *countNode;
@property (nonatomic, assign) NSInteger likesCount;
@property (nonatomic, assign) BOOL liked;
@end
@implementation LikesNode @implementation LikesNode
- (instancetype)initWithLikesCount:(NSInteger)likesCount { - (instancetype)initWithLikesCount:(NSInteger)likesCount {
self = [super init]; self = [super init];
if (self) {
if(self) {
_likesCount = likesCount; _likesCount = likesCount;
_liked = (_likesCount > 0) ? [LikesNode getYesOrNo] : NO; _liked = (_likesCount > 0) ? [LikesNode getYesOrNo] : NO;
@ -28,16 +33,12 @@
[self addSubnode:_iconNode]; [self addSubnode:_iconNode];
_countNode = [[ASTextNode alloc] init]; _countNode = [[ASTextNode alloc] init];
if(_likesCount > 0) { if (_likesCount > 0) {
if(_liked) { NSDictionary *attributes = _liked ? [TextStyles cellControlColoredStyle] : [TextStyles cellControlStyle];
_countNode.attributedString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%ld", (long)_likesCount] attributes:[TextStyles cellControlColoredStyle]]; _countNode.attributedString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%ld", (long)_likesCount] attributes:attributes];
}else {
_countNode.attributedString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%ld", (long)_likesCount] attributes:[TextStyles cellControlStyle]];
}
} }
[self addSubnode:_countNode]; [self addSubnode:_countNode];
// make it tappable easily // make it tappable easily
@ -51,8 +52,9 @@
+ (BOOL) getYesOrNo + (BOOL) getYesOrNo
{ {
int tmp = (arc4random() % 30)+1; int tmp = (arc4random() % 30)+1;
if(tmp % 5 == 0) if (tmp % 5 == 0) {
return YES; return YES;
}
return NO; return NO;
} }
@ -61,13 +63,9 @@
ASStackLayoutSpec *mainStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:6.0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsCenter children:@[_iconNode, _countNode]]; ASStackLayoutSpec *mainStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:6.0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsCenter children:@[_iconNode, _countNode]];
// set sizeRange to make width fixed to 60 // set sizeRange to make width fixed to 60
mainStack.sizeRange = ASRelativeSizeRangeMake(ASRelativeSizeMake( ASRelativeSize min = ASRelativeSizeMake(ASRelativeDimensionMakeWithPoints(60.0), ASRelativeDimensionMakeWithPoints(0.0));
ASRelativeDimensionMakeWithPoints(60.0), ASRelativeSize max = ASRelativeSizeMake(ASRelativeDimensionMakeWithPoints(60.0), ASRelativeDimensionMakeWithPoints(40.0));
ASRelativeDimensionMakeWithPoints(0.0) mainStack.sizeRange = ASRelativeSizeRangeMake(min, max);
), ASRelativeSizeMake(
ASRelativeDimensionMakeWithPoints(60.0),
ASRelativeDimensionMakeWithPoints(40.0)
));
return [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[mainStack]]; return [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[mainStack]];
} }

View File

@ -13,12 +13,12 @@
@interface Post : NSObject @interface Post : NSObject
@property (nonatomic, strong) NSString *username; @property (nonatomic, copy) NSString *username;
@property (nonatomic, strong) NSString *name; @property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) NSString *photo; @property (nonatomic, copy) NSString *photo;
@property (nonatomic, strong) NSString *post; @property (nonatomic, copy) NSString *post;
@property (nonatomic, strong) NSString *time; @property (nonatomic, copy) NSString *time;
@property (nonatomic, strong) NSString *media; @property (nonatomic, copy) NSString *media;
@property (nonatomic, assign) NSInteger via; @property (nonatomic, assign) NSInteger via;
@property (nonatomic, assign) NSInteger likes; @property (nonatomic, assign) NSInteger likes;

View File

@ -10,28 +10,10 @@
*/ */
#import <AsyncDisplayKit/AsyncDisplayKit.h> #import <AsyncDisplayKit/AsyncDisplayKit.h>
#import "Post.h"
@class LikesNode; @class Post;
@class CommentsNode;
@interface PostNode : ASCellNode <ASTextNodeDelegate> { @interface PostNode : ASCellNode
Post *_post;
ASDisplayNode *_divider;
ASTextNode *_nameNode;
ASTextNode *_usernameNode;
ASTextNode *_timeNode;
ASTextNode *_postNode;
ASImageNode *_viaNode;
ASNetworkImageNode *_avatarNode;
ASNetworkImageNode *_mediaNode;
LikesNode *_likesNode;
CommentsNode *_commentsNode;
ASImageNode *_optionsNode;
}
- (instancetype)initWithPost:(Post *)post; - (instancetype)initWithPost:(Post *)post;

View File

@ -10,11 +10,26 @@
*/ */
#import "PostNode.h" #import "PostNode.h"
#import "Post.h"
#import "TextStyles.h" #import "TextStyles.h"
#import "LikesNode.h" #import "LikesNode.h"
#import "CommentsNode.h" #import "CommentsNode.h"
@interface PostNode() <ASNetworkImageNodeDelegate> @interface PostNode() <ASNetworkImageNodeDelegate, ASTextNodeDelegate>
@property (strong, nonatomic) Post *post;
@property (strong, nonatomic) ASDisplayNode *divider;
@property (strong, nonatomic) ASTextNode *nameNode;
@property (strong, nonatomic) ASTextNode *usernameNode;
@property (strong, nonatomic) ASTextNode *timeNode;
@property (strong, nonatomic) ASTextNode *postNode;
@property (strong, nonatomic) ASImageNode *viaNode;
@property (strong, nonatomic) ASNetworkImageNode *avatarNode;
@property (strong, nonatomic) ASNetworkImageNode *mediaNode;
@property (strong, nonatomic) LikesNode *likesNode;
@property (strong, nonatomic) CommentsNode *commentsNode;
@property (strong, nonatomic) ASImageNode *optionsNode;
@end @end
@implementation PostNode @implementation PostNode
@ -22,41 +37,35 @@
- (instancetype)initWithPost:(Post *)post { - (instancetype)initWithPost:(Post *)post {
self = [super init]; self = [super init];
if (self) {
if(self) {
_post = post; _post = post;
// name node // Name node
_nameNode = [[ASTextNode alloc] init]; _nameNode = [[ASTextNode alloc] init];
_nameNode.attributedString = [[NSAttributedString alloc] initWithString:_post.name _nameNode.attributedString = [[NSAttributedString alloc] initWithString:_post.name attributes:[TextStyles nameStyle]];
attributes:[TextStyles nameStyle]];
_nameNode.maximumNumberOfLines = 1; _nameNode.maximumNumberOfLines = 1;
[self addSubnode:_nameNode]; [self addSubnode:_nameNode];
// username node // Username node
_usernameNode = [[ASTextNode alloc] init]; _usernameNode = [[ASTextNode alloc] init];
_usernameNode.attributedString = [[NSAttributedString alloc] initWithString:_post.username _usernameNode.attributedString = [[NSAttributedString alloc] initWithString:_post.username attributes:[TextStyles usernameStyle]];
attributes:[TextStyles usernameStyle]];
_usernameNode.flexShrink = YES; //if name and username don't fit to cell width, allow username shrink _usernameNode.flexShrink = YES; //if name and username don't fit to cell width, allow username shrink
_usernameNode.truncationMode = NSLineBreakByTruncatingTail; _usernameNode.truncationMode = NSLineBreakByTruncatingTail;
_usernameNode.maximumNumberOfLines = 1; _usernameNode.maximumNumberOfLines = 1;
[self addSubnode:_usernameNode]; [self addSubnode:_usernameNode];
// time node // Time node
_timeNode = [[ASTextNode alloc] init]; _timeNode = [[ASTextNode alloc] init];
_timeNode.attributedString = [[NSAttributedString alloc] initWithString:_post.time _timeNode.attributedString = [[NSAttributedString alloc] initWithString:_post.time attributes:[TextStyles timeStyle]];
attributes:[TextStyles timeStyle]];
[self addSubnode:_timeNode]; [self addSubnode:_timeNode];
// post node // Post node
_postNode = [[ASTextNode alloc] init]; _postNode = [[ASTextNode alloc] init];
// processing URLs in post // Processing URLs in post
NSString *kLinkAttributeName = @"TextLinkAttributeName"; NSString *kLinkAttributeName = @"TextLinkAttributeName";
if(![_post.post isEqualToString:@""]) { if (![_post.post isEqualToString:@""]) {
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:_post.post attributes:[TextStyles postStyle]]; NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:_post.post attributes:[TextStyles postStyle]];
@ -75,7 +84,7 @@
}]; }];
// configure node to support tappable links // Configure node to support tappable links
_postNode.delegate = self; _postNode.delegate = self;
_postNode.userInteractionEnabled = YES; _postNode.userInteractionEnabled = YES;
_postNode.linkAttributeNames = @[ kLinkAttributeName ]; _postNode.linkAttributeNames = @[ kLinkAttributeName ];
@ -85,9 +94,9 @@
[self addSubnode:_postNode]; [self addSubnode:_postNode];
// media
if(![_post.media isEqualToString:@""]) { // Media
if (![_post.media isEqualToString:@""]) {
_mediaNode = [[ASNetworkImageNode alloc] init]; _mediaNode = [[ASNetworkImageNode alloc] init];
_mediaNode.backgroundColor = ASDisplayNodeDefaultPlaceholderColor(); _mediaNode.backgroundColor = ASDisplayNodeDefaultPlaceholderColor();
@ -113,7 +122,7 @@
[self addSubnode:_mediaNode]; [self addSubnode:_mediaNode];
} }
// user pic // User pic
_avatarNode = [[ASNetworkImageNode alloc] init]; _avatarNode = [[ASNetworkImageNode alloc] init];
_avatarNode.backgroundColor = ASDisplayNodeDefaultPlaceholderColor(); _avatarNode.backgroundColor = ASDisplayNodeDefaultPlaceholderColor();
_avatarNode.preferredFrameSize = CGSizeMake(44, 44); _avatarNode.preferredFrameSize = CGSizeMake(44, 44);
@ -137,19 +146,19 @@
}; };
[self addSubnode:_avatarNode]; [self addSubnode:_avatarNode];
// hairline cell separator // Hairline cell separator
_divider = [[ASDisplayNode alloc] init]; _divider = [[ASDisplayNode alloc] init];
_divider.backgroundColor = [UIColor lightGrayColor]; _divider.backgroundColor = [UIColor lightGrayColor];
[self addSubnode:_divider]; [self addSubnode:_divider];
if(_post.via != 0) { // Via
if (_post.via != 0) {
_viaNode = [[ASImageNode alloc] init]; _viaNode = [[ASImageNode alloc] init];
_viaNode.image = (_post.via == 1) ? [UIImage imageNamed:@"icon_ios.png"] : [UIImage imageNamed:@"icon_android.png"]; _viaNode.image = (_post.via == 1) ? [UIImage imageNamed:@"icon_ios.png"] : [UIImage imageNamed:@"icon_android.png"];
[self addSubnode:_viaNode]; [self addSubnode:_viaNode];
} }
// bottom controls // Bottom controls
_likesNode = [[LikesNode alloc] initWithLikesCount:_post.likes]; _likesNode = [[LikesNode alloc] initWithLikesCount:_post.likes];
[self addSubnode:_likesNode]; [self addSubnode:_likesNode];
@ -159,9 +168,7 @@
_optionsNode = [[ASImageNode alloc] init]; _optionsNode = [[ASImageNode alloc] init];
_optionsNode.image = [UIImage imageNamed:@"icon_more"]; _optionsNode.image = [UIImage imageNamed:@"icon_more"];
[self addSubnode:_optionsNode]; [self addSubnode:_optionsNode];
} }
return self; return self;
} }
@ -175,50 +182,33 @@
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize { - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize {
//Flexible spacer between username and time // Flexible spacer between username and time
ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init]; ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init];
spacer.flexGrow = YES; spacer.flexGrow = YES;
//Horizontal stack for name, username, via icon and time // Horizontal stack for name, username, via icon and time
ASStackLayoutSpec *nameStack; NSMutableArray *layoutSpecChildren = [@[_nameNode, _usernameNode, spacer] mutableCopy];
if (_post.via != 0) {
//Cases with or without via icon [layoutSpecChildren addObject:_viaNode];
if(_post.via != 0) {
nameStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:5.0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsCenter children:@[_nameNode, _usernameNode, spacer, _viaNode, _timeNode]];
}else {
nameStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:5.0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsCenter children:@[_nameNode, _usernameNode, spacer, _timeNode]];
} }
[layoutSpecChildren addObject:_timeNode];
ASStackLayoutSpec *nameStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:5.0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsCenter children:layoutSpecChildren];
nameStack.alignSelf = ASStackLayoutAlignSelfStretch; nameStack.alignSelf = ASStackLayoutAlignSelfStretch;
// bottom controls horizontal stack // bottom controls horizontal stack
ASStackLayoutSpec *controlsStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:10 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsCenter children:@[_likesNode, _commentsNode, _optionsNode]]; ASStackLayoutSpec *controlsStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:10 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsCenter children:@[_likesNode, _commentsNode, _optionsNode]];
//add more gaps for control line // Add more gaps for control line
controlsStack.spacingAfter = 3.0; controlsStack.spacingAfter = 3.0;
controlsStack.spacingBefore = 3.0; controlsStack.spacingBefore = 3.0;
NSMutableArray *mainStackContent = [[NSMutableArray alloc] init]; NSMutableArray *mainStackContent = [[NSMutableArray alloc] init];
[mainStackContent addObject:nameStack]; [mainStackContent addObject:nameStack];
[mainStackContent addObject:_postNode]; [mainStackContent addObject:_postNode];
if(![_post.media isEqualToString:@""]) { if (![_post.media isEqualToString:@""]) {
CGFloat imageRatio = (_mediaNode.image != nil ? _mediaNode.image.size.height / _mediaNode.image.size.width : 0.5);
CGFloat imageRatio;
if(_mediaNode.image != nil) {
imageRatio = _mediaNode.image.size.height / _mediaNode.image.size.width;
}else {
imageRatio = 0.5;
}
ASRatioLayoutSpec *imagePlace = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:imageRatio child:_mediaNode]; ASRatioLayoutSpec *imagePlace = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:imageRatio child:_mediaNode];
imagePlace.spacingAfter = 3.0; imagePlace.spacingAfter = 3.0;
imagePlace.spacingBefore = 3.0; imagePlace.spacingBefore = 3.0;
@ -226,14 +216,17 @@
[mainStackContent addObject:imagePlace]; [mainStackContent addObject:imagePlace];
} }
[mainStackContent addObject:controlsStack]; [mainStackContent addObject:controlsStack];
//Vertical spec of cell main content // Vertical spec of cell main content
ASStackLayoutSpec *contentSpec = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical spacing:8.0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsStart children:mainStackContent]; ASStackLayoutSpec *contentSpec = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical spacing:8.0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsStart children:mainStackContent];
contentSpec.alignItems = ASStackLayoutAlignSelfStretch;
contentSpec.flexShrink = YES;
// Horizontal spec for avatar
ASStackLayoutSpec *avatarContentSpec = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:8.0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsStart children:@[_avatarNode, contentSpec]];
return [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsMake(10, 64, 10, 10) child:contentSpec]; return [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsMake(10, 10, 10, 10) child:avatarContentSpec];
} }
@ -244,26 +237,23 @@
// Manually layout the divider. // Manually layout the divider.
CGFloat pixelHeight = 1.0f / [[UIScreen mainScreen] scale]; CGFloat pixelHeight = 1.0f / [[UIScreen mainScreen] scale];
_divider.frame = CGRectMake(0.0f, 0.0f, self.calculatedSize.width, pixelHeight); _divider.frame = CGRectMake(0.0f, 0.0f, self.calculatedSize.width, pixelHeight);
_avatarNode.frame = CGRectMake(10, 10, 44, 44);
} }
#pragma mark - #pragma mark - ASTextNodeDelegate methods.
#pragma mark ASTextNodeDelegate methods.
- (BOOL)textNode:(ASTextNode *)richTextNode shouldHighlightLinkAttribute:(NSString *)attribute value:(id)value atPoint:(CGPoint)point - (BOOL)textNode:(ASTextNode *)richTextNode shouldHighlightLinkAttribute:(NSString *)attribute value:(id)value atPoint:(CGPoint)point
{ {
// opt into link highlighting -- tap and hold the link to try it! must enable highlighting on a layer, see -didLoad // Opt into link highlighting -- tap and hold the link to try it! must enable highlighting on a layer, see -didLoad
return YES; return YES;
} }
- (void)textNode:(ASTextNode *)richTextNode tappedLinkAttribute:(NSString *)attribute value:(NSURL *)URL atPoint:(CGPoint)point textRange:(NSRange)textRange - (void)textNode:(ASTextNode *)richTextNode tappedLinkAttribute:(NSString *)attribute value:(NSURL *)URL atPoint:(CGPoint)point textRange:(NSRange)textRange
{ {
// the node tapped a link, open it // The node tapped a link, open it
[[UIApplication sharedApplication] openURL:URL]; [[UIApplication sharedApplication] openURL:URL];
} }
#pragma mark - #pragma mark - ASNetworkImageNodeDelegate methods.
#pragma mark ASNetworkImageNodeDelegate methods.
- (void)imageNode:(ASNetworkImageNode *)imageNode didLoadImage:(UIImage *)image - (void)imageNode:(ASNetworkImageNode *)imageNode didLoadImage:(UIImage *)image
{ {

View File

@ -15,46 +15,46 @@
#import <AsyncDisplayKit/AsyncDisplayKit.h> #import <AsyncDisplayKit/AsyncDisplayKit.h>
#import <AsyncDisplayKit/ASAssert.h> #import <AsyncDisplayKit/ASAssert.h>
#include <stdlib.h> #include <stdlib.h>
@interface ViewController () <ASTableViewDataSource, ASTableViewDelegate> @interface ViewController () <ASTableViewDataSource, ASTableViewDelegate>
{
ASTableView *_tableView;
NSMutableArray *_socialAppDataSource; @property (nonatomic, strong) ASTableView *tableView;
@property (nonatomic, strong) NSMutableArray *socialAppDataSource;
}
@end @end
@implementation ViewController @implementation ViewController
- (instancetype)init - (instancetype)init
{ {
if (!(self = [super init])) self = [super init];
return nil; if (self) {
_tableView = [[ASTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain asyncDataFetching:YES];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone; // SocialAppNode has its own separator
_tableView.asyncDataSource = self;
_tableView.asyncDelegate = self;
[self createSocialAppDataSource];
self.title = @"Timeline"; self.title = @"Timeline";
[self createSocialAppDataSource];
}
return self; return self;
} }
- (void)dealloc
{
_tableView.asyncDataSource = nil;
_tableView.asyncDelegate = nil;
}
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
[self.view addSubview:_tableView];
}
- (void)viewWillLayoutSubviews self.tableView = [[ASTableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain asyncDataFetching:YES];
{ self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_tableView.frame = self.view.bounds; self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; // SocialAppNode has its own separator
self.tableView.asyncDataSource = self;
self.tableView.asyncDelegate = self;
[self.view addSubview:self.tableView];
} }
- (BOOL)prefersStatusBarHidden - (BOOL)prefersStatusBarHidden
@ -76,7 +76,6 @@
newPost.via = 0; newPost.via = 0;
newPost.likes = arc4random_uniform(74); newPost.likes = arc4random_uniform(74);
newPost.comments = arc4random_uniform(40); newPost.comments = arc4random_uniform(40);
[_socialAppDataSource addObject:newPost]; [_socialAppDataSource addObject:newPost];
newPost = [[Post alloc] init]; newPost = [[Post alloc] init];
@ -89,7 +88,6 @@
newPost.via = 1; newPost.via = 1;
newPost.likes = arc4random_uniform(74); newPost.likes = arc4random_uniform(74);
newPost.comments = arc4random_uniform(40); newPost.comments = arc4random_uniform(40);
[_socialAppDataSource addObject:newPost]; [_socialAppDataSource addObject:newPost];
newPost = [[Post alloc] init]; newPost = [[Post alloc] init];
@ -102,7 +100,6 @@
newPost.via = 2; newPost.via = 2;
newPost.likes = arc4random_uniform(74); newPost.likes = arc4random_uniform(74);
newPost.comments = arc4random_uniform(40); newPost.comments = arc4random_uniform(40);
[_socialAppDataSource addObject:newPost]; [_socialAppDataSource addObject:newPost];
newPost = [[Post alloc] init]; newPost = [[Post alloc] init];
@ -115,29 +112,28 @@
newPost.via = 1; newPost.via = 1;
newPost.likes = arc4random_uniform(74); newPost.likes = arc4random_uniform(74);
newPost.comments = arc4random_uniform(40); newPost.comments = arc4random_uniform(40);
[_socialAppDataSource addObject:newPost]; [_socialAppDataSource addObject:newPost];
} }
#pragma mark - #pragma mark - ASTableView
#pragma mark ASTableView.
- (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath - (ASCellNodeBlock)tableView:(ASTableView *)tableView nodeBlockForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{ {
Post *post = _socialAppDataSource[indexPath.row]; Post *post = self.socialAppDataSource[indexPath.row];
PostNode *node = [[PostNode alloc] initWithPost:post]; return ^{
return node; return [[PostNode alloc] initWithPost:post];
};
} }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{ {
return _socialAppDataSource.count; return self.socialAppDataSource.count;
} }
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{ {
PostNode *postNode = (PostNode *)[_tableView nodeForRowAtIndexPath:indexPath]; PostNode *postNode = (PostNode *)[_tableView nodeForRowAtIndexPath:indexPath];
Post *post = _socialAppDataSource[indexPath.row]; Post *post = self.socialAppDataSource[indexPath.row];
BOOL shouldRasterize = postNode.shouldRasterizeDescendants; BOOL shouldRasterize = postNode.shouldRasterizeDescendants;
shouldRasterize = !shouldRasterize; shouldRasterize = !shouldRasterize;