From b58e8344c0b196fca6e434051f97bf7b0ef47790 Mon Sep 17 00:00:00 2001 From: ricky cancro <@pinterest.com> Date: Thu, 30 Jul 2015 16:50:11 -0700 Subject: [PATCH] Add expectedSize to ASNetworkImageNode ASNetworkImageNode defers to ASImageNode to return its calculatedSize. ASImageNode returns the size of its image. There is a good chance that ASNetworkImageNode hasn't downloaded its image yet when calculatedSize is called, so it returns a size of CGSizeZero. On top of that, it is possible that the size of the image is not actually the size that we wish to display in our node. I've added an "expectedImageSize" property that can be used to determine the calculatedSize of an ASNetworkImageNode. --- AsyncDisplayKit/ASDisplayNode.h | 8 ++++++++ AsyncDisplayKit/ASDisplayNode.mm | 15 ++++++++++++++- AsyncDisplayKit/ASImageNode.mm | 4 +++- examples/Kittens/Sample/KittenNode.mm | 6 ++---- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/AsyncDisplayKit/ASDisplayNode.h b/AsyncDisplayKit/ASDisplayNode.h index f748693040..0311a3028d 100644 --- a/AsyncDisplayKit/ASDisplayNode.h +++ b/AsyncDisplayKit/ASDisplayNode.h @@ -185,6 +185,14 @@ typedef CALayer *(^ASDisplayNodeLayerBlock)(); */ @property (nonatomic, readonly, assign) ASSizeRange constrainedSizeForCalculatedLayout; +/** + * @abstract Used by some implementations of measureWithSizeRange: to provide an intrisic content size + * to a node when one cannot be computed from its subnodes + * + * @return The preferred frame size of this node + */ +@property (atomic, assign, readwrite) CGSize preferredFrameSize; + /** @name Managing the nodes hierarchy */ diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index d9fe7520bd..b5cdf6be59 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -47,6 +47,7 @@ @synthesize flexShrink = _flexShrink; @synthesize flexBasis = _flexBasis; @synthesize alignSelf = _alignSelf; +@synthesize preferredFrameSize = _preferredFrameSize; BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector) { @@ -135,6 +136,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)()) _methodOverrides = overrides; _flexBasis = ASRelativeDimensionUnconstrained; + _preferredFrameSize = CGSizeZero; } - (id)init @@ -1330,7 +1332,7 @@ static NSInteger incrementIfFound(NSInteger i) { - (CGSize)calculateSizeThatFits:(CGSize)constrainedSize { ASDisplayNodeAssertThreadAffinity(self); - return CGSizeZero; + return _preferredFrameSize; } - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize @@ -1357,6 +1359,17 @@ static NSInteger incrementIfFound(NSInteger i) { return _constrainedSize; } +- (void)setPreferredFrameSize:(CGSize)preferredFrameSize +{ + ASDN::MutexLocker l(_propertyLock); + _preferredFrameSize = preferredFrameSize; +} + +- (CGSize)preferredFrameSize +{ + ASDN::MutexLocker l(_propertyLock); + return _preferredFrameSize; +} - (UIImage *)placeholderImage { return nil; diff --git a/AsyncDisplayKit/ASImageNode.mm b/AsyncDisplayKit/ASImageNode.mm index d7cdebbd94..2db88e5fef 100644 --- a/AsyncDisplayKit/ASImageNode.mm +++ b/AsyncDisplayKit/ASImageNode.mm @@ -111,7 +111,9 @@ - (CGSize)calculateSizeThatFits:(CGSize)constrainedSize { ASDN::MutexLocker l(_imageLock); - if (_image) + if (CGSizeEqualToSize(self.preferredFrameSize, CGSizeZero) == NO) + return CGSizeMake(MIN(constrainedSize.width, self.preferredFrameSize.width), MIN(constrainedSize.height, self.preferredFrameSize.height)); + else if (_image) return _image.size; else return CGSizeZero; diff --git a/examples/Kittens/Sample/KittenNode.mm b/examples/Kittens/Sample/KittenNode.mm index de8d0384e4..a852bcb801 100644 --- a/examples/Kittens/Sample/KittenNode.mm +++ b/examples/Kittens/Sample/KittenNode.mm @@ -134,9 +134,7 @@ static const CGFloat kInnerPadding = 10.0f; #if UseAutomaticLayout - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize { - ASRatioLayoutSpec *imagePlaceholder = [ASRatioLayoutSpec newWithRatio:1.0 child:_imageNode]; - imagePlaceholder.flexBasis = ASRelativeDimensionMakeWithPoints(kImageSize * (!_isImageEnlarged ? 1 : 2)); - + _imageNode.preferredFrameSize = _isImageEnlarged ? CGSizeMake(2.0 * kImageSize, 2.0 * kImageSize) : CGSizeMake(kImageSize, kImageSize); _textNode.flexShrink = YES; return @@ -148,7 +146,7 @@ static const CGFloat kInnerPadding = 10.0f; .direction = ASStackLayoutDirectionHorizontal, .spacing = kInnerPadding } - children:!_swappedTextAndImage ? @[imagePlaceholder, _textNode] : @[_textNode, imagePlaceholder]]]; + children:!_swappedTextAndImage ? @[_imageNode, _textNode] : @[_textNode, _imageNode]]]; } // With box model, you don't need to override this method, unless you want to add custom logic.