diff --git a/examples/CatDealsCollectionView/Sample/BlurbNode.h b/examples/CatDealsCollectionView/Sample/BlurbNode.h index e6574bcd05..e40f99d8a6 100644 --- a/examples/CatDealsCollectionView/Sample/BlurbNode.h +++ b/examples/CatDealsCollectionView/Sample/BlurbNode.h @@ -1,18 +1,18 @@ // // BlurbNode.h -// Sample +// Texture // // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // This source code is licensed under the BSD-style license found in the -// LICENSE file in the root directory of this source tree. An additional grant -// of patent rights can be found in the PATENTS file in the same directory. +// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional +// grant of patent rights can be found in the PATENTS file in the same directory. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present, +// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // #import diff --git a/examples/CatDealsCollectionView/Sample/BlurbNode.m b/examples/CatDealsCollectionView/Sample/BlurbNode.m index 7dbe86a8b8..0b358273c0 100644 --- a/examples/CatDealsCollectionView/Sample/BlurbNode.m +++ b/examples/CatDealsCollectionView/Sample/BlurbNode.m @@ -1,18 +1,18 @@ // // BlurbNode.m -// Sample +// Texture // // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // This source code is licensed under the BSD-style license found in the -// LICENSE file in the root directory of this source tree. An additional grant -// of patent rights can be found in the PATENTS file in the same directory. +// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional +// grant of patent rights can be found in the PATENTS file in the same directory. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present, +// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // #import "BlurbNode.h" @@ -57,16 +57,15 @@ static CGFloat kTextPadding = 10.0f; NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:blurb]; [string addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue-Light" size:16.0f] range:NSMakeRange(0, blurb.length)]; [string addAttributes:@{ - NSLinkAttributeName: [NSURL URLWithString:@"http://lorempixel.com/"], - NSForegroundColorAttributeName: [UIColor blueColor], - NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle | NSUnderlinePatternDot), - } - range:[blurb rangeOfString:@"lorempixel.com"]]; + NSLinkAttributeName: [NSURL URLWithString:@"http://lorempixel.com/"], + NSForegroundColorAttributeName: [UIColor blueColor], + NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle | NSUnderlinePatternDot), + } range:[blurb rangeOfString:@"lorempixel.com"]]; [string addAttributes:@{ - NSLinkAttributeName: [NSURL URLWithString:@"http://www.catipsum.com/"], - NSForegroundColorAttributeName: [UIColor blueColor], - NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle | NSUnderlinePatternDot), - } range:[blurb rangeOfString:@"catipsum.com"]]; + NSLinkAttributeName: [NSURL URLWithString:@"http://www.catipsum.com/"], + NSForegroundColorAttributeName: [UIColor blueColor], + NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle | NSUnderlinePatternDot), + } range:[blurb rangeOfString:@"catipsum.com"]]; _textNode.attributedText = string; // add it as a subnode, and we're done @@ -90,7 +89,7 @@ static CGFloat kTextPadding = 10.0f; centerSpec.sizingOptions = ASCenterLayoutSpecSizingOptionMinimumY; centerSpec.child = _textNode; - UIEdgeInsets padding =UIEdgeInsetsMake(kTextPadding, kTextPadding, kTextPadding, kTextPadding); + UIEdgeInsets padding = UIEdgeInsetsMake(kTextPadding, kTextPadding, kTextPadding, kTextPadding); return [ASInsetLayoutSpec insetLayoutSpecWithInsets:padding child:centerSpec]; } diff --git a/examples/CatDealsCollectionView/Sample/ItemNode.h b/examples/CatDealsCollectionView/Sample/ItemNode.h index 678327e111..bb0f06857d 100644 --- a/examples/CatDealsCollectionView/Sample/ItemNode.h +++ b/examples/CatDealsCollectionView/Sample/ItemNode.h @@ -20,7 +20,6 @@ @interface ItemNode : ASCellNode -- initWithViewModel:(ItemViewModel *)viewModel; + (CGSize)sizeForWidth:(CGFloat)width; + (CGSize)preferredViewSize; diff --git a/examples/CatDealsCollectionView/Sample/ItemNode.m b/examples/CatDealsCollectionView/Sample/ItemNode.m index 400f5b79e8..4fd76e8a01 100644 --- a/examples/CatDealsCollectionView/Sample/ItemNode.m +++ b/examples/CatDealsCollectionView/Sample/ItemNode.m @@ -20,6 +20,16 @@ #import "PlaceholderNetworkImageNode.h" #import +static CGFloat ASIsRTL() +{ + static BOOL __isRTL = NO; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + __isRTL = [UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft; + }); + return __isRTL; +} + const CGFloat kFixedLabelsAreaHeight = 96.0; const CGFloat kDesignWidth = 320.0; const CGFloat kDesignHeight = 299.0; @@ -28,7 +38,7 @@ const CGFloat kSoldOutGBHeight = 50.0; @interface ItemNode() -@property (nonatomic, strong) ItemViewModel *viewModel; +@property (nonatomic, strong) ItemViewModel *nodeModel; @property (nonatomic, strong) PlaceholderNetworkImageNode *dealImageView; @@ -46,28 +56,35 @@ const CGFloat kSoldOutGBHeight = 50.0; @end @implementation ItemNode -@dynamic viewModel; +// Defined on ASCellNode +@dynamic nodeModel; -- (instancetype)initWithViewModel:(ItemViewModel *)viewModel ++ (void)load +{ + // Need to happen on main thread. + ASIsRTL(); +} + +- (instancetype)init { self = [super init]; if (self != nil) { - self.viewModel = viewModel; - [self setup]; - [self updateLabels]; + [self setupNodes]; [self updateBackgroundColor]; - - ASSetDebugName(self, @"Item #%zd", viewModel.identifier); - self.accessibilityIdentifier = viewModel.titleText; } return self; } -+ (BOOL)isRTL { - return [UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft; +- (void)setNodeModel:(ItemViewModel *)nodeModel +{ + [super setNodeModel:nodeModel]; + + [self updateLabels]; + [self updateAccessibilityIdentifier]; } -- (void)setup { +- (void)setupNodes +{ self.dealImageView = [[PlaceholderNetworkImageNode alloc] init]; self.dealImageView.delegate = self; self.dealImageView.placeholderEnabled = YES; @@ -138,7 +155,7 @@ const CGFloat kSoldOutGBHeight = 50.0; self.soldOutLabelBackground.hidden = YES; self.soldOutLabelFlat.hidden = YES; - if ([ItemNode isRTL]) { + if (ASIsRTL()) { self.titleLabel.style.alignSelf = ASStackLayoutAlignSelfEnd; self.firstInfoLabel.style.alignSelf = ASStackLayoutAlignSelfEnd; self.distanceLabel.style.alignSelf = ASStackLayoutAlignSelfEnd; @@ -154,49 +171,56 @@ const CGFloat kSoldOutGBHeight = 50.0; } } -- (void)updateLabels { +- (void)updateLabels +{ // Set Title text - if (self.viewModel.titleText) { - self.titleLabel.attributedText = [[NSAttributedString alloc] initWithString:self.viewModel.titleText attributes:[ItemStyles titleStyle]]; + if (self.nodeModel.titleText) { + self.titleLabel.attributedText = [[NSAttributedString alloc] initWithString:self.nodeModel.titleText attributes:[ItemStyles titleStyle]]; } - if (self.viewModel.firstInfoText) { - self.firstInfoLabel.attributedText = [[NSAttributedString alloc] initWithString:self.viewModel.firstInfoText attributes:[ItemStyles subtitleStyle]]; + if (self.nodeModel.firstInfoText) { + self.firstInfoLabel.attributedText = [[NSAttributedString alloc] initWithString:self.nodeModel.firstInfoText attributes:[ItemStyles subtitleStyle]]; } - if (self.viewModel.secondInfoText) { - self.secondInfoLabel.attributedText = [[NSAttributedString alloc] initWithString:self.viewModel.secondInfoText attributes:[ItemStyles secondInfoStyle]]; + if (self.nodeModel.secondInfoText) { + self.secondInfoLabel.attributedText = [[NSAttributedString alloc] initWithString:self.nodeModel.secondInfoText attributes:[ItemStyles secondInfoStyle]]; } - if (self.viewModel.originalPriceText) { - self.originalPriceLabel.attributedText = [[NSAttributedString alloc] initWithString:self.viewModel.originalPriceText attributes:[ItemStyles originalPriceStyle]]; + if (self.nodeModel.originalPriceText) { + self.originalPriceLabel.attributedText = [[NSAttributedString alloc] initWithString:self.nodeModel.originalPriceText attributes:[ItemStyles originalPriceStyle]]; } - if (self.viewModel.finalPriceText) { - self.finalPriceLabel.attributedText = [[NSAttributedString alloc] initWithString:self.viewModel.finalPriceText attributes:[ItemStyles finalPriceStyle]]; + if (self.nodeModel.finalPriceText) { + self.finalPriceLabel.attributedText = [[NSAttributedString alloc] initWithString:self.nodeModel.finalPriceText attributes:[ItemStyles finalPriceStyle]]; } - if (self.viewModel.distanceLabelText) { - NSString *format = [ItemNode isRTL] ? @"%@ •" : @"• %@"; - NSString *distanceText = [NSString stringWithFormat:format, self.viewModel.distanceLabelText]; + if (self.nodeModel.distanceLabelText) { + NSString *format = ASIsRTL() ? @"%@ •" : @"• %@"; + NSString *distanceText = [NSString stringWithFormat:format, self.nodeModel.distanceLabelText]; self.distanceLabel.attributedText = [[NSAttributedString alloc] initWithString:distanceText attributes:[ItemStyles distanceStyle]]; } - BOOL isSoldOut = self.viewModel.soldOutText != nil; + BOOL isSoldOut = self.nodeModel.soldOutText != nil; if (isSoldOut) { - NSString *soldOutText = self.viewModel.soldOutText; + NSString *soldOutText = self.nodeModel.soldOutText; self.soldOutLabelFlat.attributedText = [[NSAttributedString alloc] initWithString:soldOutText attributes:[ItemStyles soldOutStyle]]; } self.soldOutOverlay.hidden = !isSoldOut; self.soldOutLabelFlat.hidden = !isSoldOut; self.soldOutLabelBackground.hidden = !isSoldOut; - BOOL hasBadge = self.viewModel.badgeText != nil; + BOOL hasBadge = self.nodeModel.badgeText != nil; if (hasBadge) { - self.badge.attributedText = [[NSAttributedString alloc] initWithString:self.viewModel.badgeText attributes:[ItemStyles badgeStyle]]; + self.badge.attributedText = [[NSAttributedString alloc] initWithString:self.nodeModel.badgeText attributes:[ItemStyles badgeStyle]]; self.badge.backgroundColor = [ItemStyles badgeColor]; } self.badge.hidden = !hasBadge; } +- (void)updateAccessibilityIdentifier +{ + ASSetDebugName(self, @"Item #%zd", self.nodeModel.identifier); + self.accessibilityIdentifier = self.nodeModel.titleText; +} + - (void)updateBackgroundColor { if (self.highlighted) { @@ -208,9 +232,6 @@ const CGFloat kSoldOutGBHeight = 50.0; } } -- (void)imageNode:(ASNetworkImageNode *)imageNode didLoadImage:(UIImage *)image { -} - - (void)setSelected:(BOOL)selected { [super setSelected:selected]; @@ -223,21 +244,22 @@ const CGFloat kSoldOutGBHeight = 50.0; [self updateBackgroundColor]; } -#pragma mark - superclass +#pragma mark - ASDisplayNode -- (void)displayWillStart { +- (void)displayWillStart +{ [super displayWillStart]; [self didEnterPreloadState]; } -- (void)didEnterPreloadState { +- (void)didEnterPreloadState +{ [super didEnterPreloadState]; - if (self.viewModel) { + if (self.nodeModel) { [self loadImage]; } } - - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize { ASLayoutSpec *textSpec = [self textSpec]; @@ -253,7 +275,8 @@ const CGFloat kSoldOutGBHeight = 50.0; return soldOutOverlay; } -- (ASLayoutSpec *)textSpec { +- (ASLayoutSpec *)textSpec +{ CGFloat kInsetHorizontal = 16.0; CGFloat kInsetTop = 6.0; CGFloat kInsetBottom = 0.0; @@ -271,7 +294,7 @@ const CGFloat kSoldOutGBHeight = 50.0; NSArray *info1Children = @[self.firstInfoLabel, self.distanceLabel, horizontalSpacer1, self.originalPriceLabel]; NSArray *info2Children = @[self.secondInfoLabel, horizontalSpacer2, self.finalPriceLabel]; - if ([ItemNode isRTL]) { + if (ASIsRTL()) { info1Children = [[info1Children reverseObjectEnumerator] allObjects]; info2Children = [[info2Children reverseObjectEnumerator] allObjects]; } @@ -288,7 +311,8 @@ const CGFloat kSoldOutGBHeight = 50.0; return textWrapper; } -- (ASLayoutSpec *)imageSpecWithSize:(ASSizeRange)constrainedSize { +- (ASLayoutSpec *)imageSpecWithSize:(ASSizeRange)constrainedSize +{ CGFloat imageRatio = [self imageRatioFromSize:constrainedSize.max]; ASRatioLayoutSpec *imagePlace = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:imageRatio child:self.dealImageView]; @@ -310,34 +334,38 @@ const CGFloat kSoldOutGBHeight = 50.0; return soldOutLabelOverBackground; } - -+ (CGSize)sizeForWidth:(CGFloat)width { ++ (CGSize)sizeForWidth:(CGFloat)width +{ CGFloat height = [self scaledHeightForPreferredSize:[self preferredViewSize] scaledWidth:width]; return CGSizeMake(width, height); } -+ (CGSize)preferredViewSize { ++ (CGSize)preferredViewSize +{ return CGSizeMake(kDesignWidth, kDesignHeight); } -+ (CGFloat)scaledHeightForPreferredSize:(CGSize)preferredSize scaledWidth:(CGFloat)scaledWidth { ++ (CGFloat)scaledHeightForPreferredSize:(CGSize)preferredSize scaledWidth:(CGFloat)scaledWidth +{ CGFloat scale = scaledWidth / kDesignWidth; CGFloat scaledHeight = ceilf(scale * (kDesignHeight - kFixedLabelsAreaHeight)) + kFixedLabelsAreaHeight; return scaledHeight; } -#pragma mark - view operations +#pragma mark - Image -- (CGFloat)imageRatioFromSize:(CGSize)size { +- (CGFloat)imageRatioFromSize:(CGSize)size +{ CGFloat imageHeight = size.height - kFixedLabelsAreaHeight; CGFloat imageRatio = imageHeight / size.width; return imageRatio; } -- (CGSize)imageSize { +- (CGSize)imageSize +{ if (!CGSizeEqualToSize(self.dealImageView.frame.size, CGSizeZero)) { return self.dealImageView.frame.size; } else if (!CGSizeEqualToSize(self.calculatedSize, CGSizeZero)) { @@ -349,13 +377,14 @@ const CGFloat kSoldOutGBHeight = 50.0; } } -- (void)loadImage { +- (void)loadImage +{ CGSize imageSize = [self imageSize]; if (CGSizeEqualToSize(CGSizeZero, imageSize)) { return; } - NSURL *url = [self.viewModel imageURLWithSize:imageSize]; + NSURL *url = [self.nodeModel imageURLWithSize:imageSize]; // if we're trying to set the deal image to what it already was, skip the work if ([[url absoluteString] isEqualToString:[self.dealImageView.URL absoluteString]]) { diff --git a/examples/CatDealsCollectionView/Sample/ItemStyles.h b/examples/CatDealsCollectionView/Sample/ItemStyles.h index a5af90a017..09d3b81c88 100644 --- a/examples/CatDealsCollectionView/Sample/ItemStyles.h +++ b/examples/CatDealsCollectionView/Sample/ItemStyles.h @@ -1,20 +1,18 @@ // // ItemStyles.h -// Sample -// -// Created by Samuel Stow on 12/30/15. +// Texture // // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // This source code is licensed under the BSD-style license found in the -// LICENSE file in the root directory of this source tree. An additional grant -// of patent rights can be found in the PATENTS file in the same directory. +// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional +// grant of patent rights can be found in the PATENTS file in the same directory. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present, +// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // #import diff --git a/examples/CatDealsCollectionView/Sample/ItemStyles.m b/examples/CatDealsCollectionView/Sample/ItemStyles.m index 12871e3be1..690980d49c 100644 --- a/examples/CatDealsCollectionView/Sample/ItemStyles.m +++ b/examples/CatDealsCollectionView/Sample/ItemStyles.m @@ -1,20 +1,18 @@ // // ItemStyles.m -// Sample -// -// Created by Samuel Stow on 12/30/15. +// Texture // // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // This source code is licensed under the BSD-style license found in the -// LICENSE file in the root directory of this source tree. An additional grant -// of patent rights can be found in the PATENTS file in the same directory. +// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional +// grant of patent rights can be found in the PATENTS file in the same directory. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present, +// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // #import "ItemStyles.h" @@ -95,9 +93,10 @@ UIFont *kInfoFont; + (UIImage *)placeholderImage { static UIImage *__catFace = nil; - if (!__catFace) { + static dispatch_once_t onceToken; + dispatch_once (&onceToken, ^{ __catFace = [UIImage imageNamed:@"cat_face"]; - } + }); return __catFace; } diff --git a/examples/CatDealsCollectionView/Sample/ItemViewModel.m b/examples/CatDealsCollectionView/Sample/ItemViewModel.m index 4cf925e5d6..6206e399c2 100644 --- a/examples/CatDealsCollectionView/Sample/ItemViewModel.m +++ b/examples/CatDealsCollectionView/Sample/ItemViewModel.m @@ -35,7 +35,8 @@ NSArray *badges; return [[ItemViewModel alloc] init]; } -- (instancetype)init { +- (instancetype)init +{ self = [super init]; if (self) { static _Atomic(NSInteger) nextID = ATOMIC_VAR_INIT(1); @@ -45,11 +46,9 @@ NSArray *badges; _secondInfoText = [NSString stringWithFormat:@"%zd+ bought", [self randomNumberInRange:5 to:6000]]; _originalPriceText = [NSString stringWithFormat:@"$%zd", [self randomNumberInRange:40 to:90]]; _finalPriceText = [NSString stringWithFormat:@"$%zd", [self randomNumberInRange:5 to:30]]; - BOOL isSoldOut = arc4random() % 5 == 0; - _soldOutText = isSoldOut ? @"SOLD OUT" : nil; + _soldOutText = (arc4random() % 5 == 0) ? @"SOLD OUT" : nil; _distanceLabelText = [NSString stringWithFormat:@"%zd mi", [self randomNumberInRange:1 to:20]]; - BOOL isBadged = arc4random() % 2 == 0; - if (isBadged) { + if (arc4random() % 2 == 0) { _badgeText = [self randomObjectFromArray:badges]; } _catNumber = [self randomNumberInRange:1 to:10]; @@ -58,18 +57,20 @@ NSArray *badges; return self; } -- (NSURL *)imageURLWithSize:(CGSize)size { +- (NSURL *)imageURLWithSize:(CGSize)size +{ NSString *imageText = [NSString stringWithFormat:@"Fun cat pic %zd", self.labelNumber]; NSString *urlString = [NSString stringWithFormat:@"http://lorempixel.com/%zd/%zd/cats/%zd/%@", (NSInteger)roundl(size.width), (NSInteger)roundl(size.height), self.catNumber, imageText]; - urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - + + urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]; return [NSURL URLWithString:urlString]; } // titles courtesy of http://www.catipsum.com/ -+ (void)initialize { ++ (void)initialize +{ titles = @[@"Leave fur on owners clothes intrigued by the shower", @"Meowwww", @"Immediately regret falling into bathtub stare out the window", diff --git a/examples/CatDealsCollectionView/Sample/LoadingNode.h b/examples/CatDealsCollectionView/Sample/LoadingNode.h index d144de01a9..6c07157265 100644 --- a/examples/CatDealsCollectionView/Sample/LoadingNode.h +++ b/examples/CatDealsCollectionView/Sample/LoadingNode.h @@ -1,20 +1,18 @@ // // LoadingNode.h -// Sample -// -// Created by Samuel Stow on 1/9/16. +// Texture // // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // This source code is licensed under the BSD-style license found in the -// LICENSE file in the root directory of this source tree. An additional grant -// of patent rights can be found in the PATENTS file in the same directory. +// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional +// grant of patent rights can be found in the PATENTS file in the same directory. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present, +// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // #import diff --git a/examples/CatDealsCollectionView/Sample/LoadingNode.m b/examples/CatDealsCollectionView/Sample/LoadingNode.m index 4fa29d6e3d..03a6825c65 100644 --- a/examples/CatDealsCollectionView/Sample/LoadingNode.m +++ b/examples/CatDealsCollectionView/Sample/LoadingNode.m @@ -1,41 +1,29 @@ // // LoadingNode.m -// Sample -// -// Created by Samuel Stow on 1/9/16. +// Texture // // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // This source code is licensed under the BSD-style license found in the -// LICENSE file in the root directory of this source tree. An additional grant -// of patent rights can be found in the PATENTS file in the same directory. +// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional +// grant of patent rights can be found in the PATENTS file in the same directory. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present, +// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // #import "LoadingNode.h" -#import -#import -#import #import -@interface LoadingNode () -{ +@implementation LoadingNode { ASDisplayNode *_loadingSpinner; } -@end - -@implementation LoadingNode - - -#pragma mark - -#pragma mark ASCellNode. +#pragma mark - ASCellNode - (instancetype)init { @@ -61,7 +49,6 @@ centerSpec.centeringOptions = ASCenterLayoutSpecCenteringXY; centerSpec.sizingOptions = ASCenterLayoutSpecSizingOptionDefault; centerSpec.child = _loadingSpinner; - return centerSpec; } diff --git a/examples/CatDealsCollectionView/Sample/PlaceholderNetworkImageNode.h b/examples/CatDealsCollectionView/Sample/PlaceholderNetworkImageNode.h index 53ba71544c..31470610bd 100644 --- a/examples/CatDealsCollectionView/Sample/PlaceholderNetworkImageNode.h +++ b/examples/CatDealsCollectionView/Sample/PlaceholderNetworkImageNode.h @@ -1,20 +1,18 @@ // // PlaceholderNetworkImageNode.h -// Sample -// -// Created by Samuel Stow on 1/14/16. +// Texture // // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // This source code is licensed under the BSD-style license found in the -// LICENSE file in the root directory of this source tree. An additional grant -// of patent rights can be found in the PATENTS file in the same directory. +// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional +// grant of patent rights can be found in the PATENTS file in the same directory. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present, +// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // #import diff --git a/examples/CatDealsCollectionView/Sample/PlaceholderNetworkImageNode.m b/examples/CatDealsCollectionView/Sample/PlaceholderNetworkImageNode.m index cb1b7e81bc..e7f0de47f9 100644 --- a/examples/CatDealsCollectionView/Sample/PlaceholderNetworkImageNode.m +++ b/examples/CatDealsCollectionView/Sample/PlaceholderNetworkImageNode.m @@ -1,29 +1,27 @@ // // PlaceholderNetworkImageNode.m -// Sample -// -// Created by Samuel Stow on 1/14/16. +// Texture // // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // This source code is licensed under the BSD-style license found in the -// LICENSE file in the root directory of this source tree. An additional grant -// of patent rights can be found in the PATENTS file in the same directory. +// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional +// grant of patent rights can be found in the PATENTS file in the same directory. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present, +// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // #import "PlaceholderNetworkImageNode.h" @implementation PlaceholderNetworkImageNode -- (UIImage *)placeholderImage { +- (UIImage *)placeholderImage +{ return self.placeholderImageOverride; } - @end diff --git a/examples/CatDealsCollectionView/Sample/ViewController.m b/examples/CatDealsCollectionView/Sample/ViewController.m index 6e63dabe09..78b58d67a6 100644 --- a/examples/CatDealsCollectionView/Sample/ViewController.m +++ b/examples/CatDealsCollectionView/Sample/ViewController.m @@ -50,7 +50,6 @@ static const CGFloat kHorizontalSectionPadding = 10.0f; self = [super initWithNode:_collectionNode]; if (self) { - self.title = @"Cat Deals"; _collectionNode.dataSource = self; @@ -89,7 +88,8 @@ static const CGFloat kHorizontalSectionPadding = 10.0f; [self fetchMoreCatsWithCompletion:nil]; } -- (void)fetchMoreCatsWithCompletion:(void (^)(BOOL))completion { +- (void)fetchMoreCatsWithCompletion:(void (^)(BOOL))completion +{ if (kSimulateWebResponse) { __weak typeof(self) weakSelf = self; void(^mockWebService)() = ^{ @@ -110,7 +110,8 @@ static const CGFloat kHorizontalSectionPadding = 10.0f; } } -- (void)appendMoreItems:(NSInteger)numberOfNewItems completion:(void (^)(BOOL))completion { +- (void)appendMoreItems:(NSInteger)numberOfNewItems completion:(void (^)(BOOL))completion +{ NSArray *newData = [self getMoreData:numberOfNewItems]; [_collectionNode performBatchAnimated:YES updates:^{ [_data addObjectsFromArray:newData]; @@ -119,7 +120,8 @@ static const CGFloat kHorizontalSectionPadding = 10.0f; } completion:completion]; } -- (NSArray *)getMoreData:(NSInteger)count { +- (NSArray *)getMoreData:(NSInteger)count +{ NSMutableArray *data = [NSMutableArray array]; for (int i = 0; i < count; i++) { [data addObject:[ItemViewModel randomItem]]; @@ -127,7 +129,8 @@ static const CGFloat kHorizontalSectionPadding = 10.0f; return data; } -- (NSArray *)indexPathsForObjects:(NSArray *)data { +- (NSArray *)indexPathsForObjects:(NSArray *)data +{ NSMutableArray *indexPaths = [NSMutableArray array]; NSInteger section = 0; for (ItemViewModel *viewModel in data) { @@ -138,7 +141,8 @@ static const CGFloat kHorizontalSectionPadding = 10.0f; return indexPaths; } -- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { +- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator +{ [_collectionNode.view.collectionViewLayout invalidateLayout]; } @@ -151,12 +155,16 @@ static const CGFloat kHorizontalSectionPadding = 10.0f; - (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath { - ItemViewModel *viewModel = _data[indexPath.item]; return ^{ - return [[ItemNode alloc] initWithViewModel:viewModel]; + return [[ItemNode alloc] init]; }; } +- (id)collectionNode:(ASCollectionNode *)collectionNode nodeModelForItemAtIndexPath:(NSIndexPath *)indexPath +{ + return _data[indexPath.item]; +} + - (ASCellNode *)collectionNode:(ASCollectionNode *)collectionNode nodeForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { if ([kind isEqualToString:UICollectionElementKindSectionHeader] && indexPath.section == 0) {