mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Get CatDealsCollectionView example running again #trivial (#783)
* Get CatDealsCollectionView example running again * Fix it for real and some other styling stuff * Fix some warning * Adjust headers
This commit is contained in:
committed by
GitHub
parent
c6454214ac
commit
5ea4d51596
@@ -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 <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
@interface ItemNode : ASCellNode
|
||||
|
||||
- initWithViewModel:(ItemViewModel *)viewModel;
|
||||
+ (CGSize)sizeForWidth:(CGFloat)width;
|
||||
+ (CGSize)preferredViewSize;
|
||||
|
||||
|
||||
@@ -20,6 +20,16 @@
|
||||
#import "PlaceholderNetworkImageNode.h"
|
||||
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
|
||||
|
||||
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() <ASNetworkImageNodeDelegate>
|
||||
|
||||
@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]]) {
|
||||
|
||||
@@ -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 <Foundation/Foundation.h>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
|
||||
@@ -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 <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
||||
#import <AsyncDisplayKit/ASHighlightOverlayLayer.h>
|
||||
|
||||
#import <AsyncDisplayKit/ASInsetLayoutSpec.h>
|
||||
#import <AsyncDisplayKit/ASCenterLayoutSpec.h>
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<UIViewControllerTransitionCoordinator>)coordinator {
|
||||
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)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) {
|
||||
|
||||
Reference in New Issue
Block a user