diff --git a/AsyncDisplayKit/ASImageNode.mm b/AsyncDisplayKit/ASImageNode.mm index 0a9c5cbbe6..38f096ce87 100644 --- a/AsyncDisplayKit/ASImageNode.mm +++ b/AsyncDisplayKit/ASImageNode.mm @@ -15,8 +15,10 @@ #import #import #import +#import #import "ASImageNode+CGExtras.h" +#import "AsyncDisplayKit+Debug.h" #import "ASInternalHelpers.h" #import "ASEqualityHelpers.h" @@ -55,6 +57,9 @@ @end +@interface ASImageNode () +@property (nonatomic, strong) ASTextNode *debugLabelNode; +@end @implementation ASImageNode { @@ -89,6 +94,12 @@ _cropRect = CGRectMake(0.5, 0.5, 0, 0); _cropDisplayBounds = CGRectNull; _placeholderColor = ASDisplayNodeDefaultPlaceholderColor(); + + if ([ASImageNode shouldShowImageDebugOverlay]) { + _debugLabelNode = [[ASTextNode alloc] init]; + _debugLabelNode.layerBacked = YES; + [self addSubnode:_debugLabelNode]; + } return self; } @@ -109,6 +120,7 @@ { ASDN::MutexLocker l(_imageLock); // if a preferredFrameSize is set, call the superclass to return that instead of using the image size. + [_debugLabelNode measure:constrainedSize]; if (CGSizeEqualToSize(self.preferredFrameSize, CGSizeZero) == NO) return [super calculateSizeThatFits:constrainedSize]; else if (_image) @@ -152,6 +164,12 @@ contentMode:self.contentMode]; } +- (NSDictionary *)debugLabelAttributes +{ + return @{ NSFontAttributeName: [UIFont systemFontOfSize:15.0], + NSForegroundColorAttributeName: [UIColor redColor] }; +} + - (UIImage *)displayWithParameters:(_ASImageNodeDrawParameters *)parameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelled { UIImage *image; @@ -202,6 +220,20 @@ CGSize imageSizeInPixels = CGSizeMake(imageSize.width * image.scale, imageSize.height * image.scale); CGSize boundsSizeInPixels = CGSizeMake(floorf(bounds.size.width * contentsScale), floorf(bounds.size.height * contentsScale)); + if (_debugLabelNode) { + // NSLog(@"widthScale = %f, heightScale = %f", imageSizeInPixels.width / boundsSizeInPixels.width, imageSizeInPixels.height / boundsSizeInPixels.height); + CGFloat pixelCountRatio = (imageSizeInPixels.width * imageSizeInPixels.height) / (boundsSizeInPixels.width * boundsSizeInPixels.height); + if (pixelCountRatio != 1.0) { + NSString *scaleString = [NSString stringWithFormat:@"%.2fx", pixelCountRatio]; + _debugLabelNode.attributedString = [[NSAttributedString alloc] initWithString:scaleString attributes:[self debugLabelAttributes]]; + _debugLabelNode.hidden = NO; + [self setNeedsLayout]; + } else { + _debugLabelNode.hidden = YES; + _debugLabelNode.attributedString = nil; + } + } + BOOL contentModeSupported = contentMode == UIViewContentModeScaleAspectFill || contentMode == UIViewContentModeScaleAspectFit || contentMode == UIViewContentModeCenter; @@ -410,9 +442,21 @@ _imageModificationBlock = imageModificationBlock; } +#pragma mark - Debug +- (void)layout +{ + [super layout]; + + if (_debugLabelNode) { + CGSize boundsSize = self.bounds.size; + CGSize debugLabelSize = [_debugLabelNode measure:boundsSize]; + CGPoint debugLabelOrigin = CGPointMake(boundsSize.width - debugLabelSize.width, + boundsSize.height - debugLabelSize.height); + _debugLabelNode.frame = (CGRect) {debugLabelOrigin, debugLabelSize}; + } +} @end - #pragma mark - Extras extern asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlock(CGFloat borderWidth, UIColor *borderColor) { @@ -460,4 +504,3 @@ extern asimagenode_modification_block_t ASImageNodeTintColorModificationBlock(UI return modifiedImage; }; } - diff --git a/AsyncDisplayKit/AsyncDisplayKit+Debug.h b/AsyncDisplayKit/AsyncDisplayKit+Debug.h new file mode 100644 index 0000000000..5eb1eaa9a1 --- /dev/null +++ b/AsyncDisplayKit/AsyncDisplayKit+Debug.h @@ -0,0 +1,21 @@ +// +// AsyncDisplayKit+Debug.h +// AsyncDisplayKit +// +// Created by Hannah Troisi on 3/7/16. +// Copyright © 2016 Facebook. All rights reserved. +// + +#import +#import "ASImageNode.h" + +@interface ASImageNode (Debug) + +/** +* Class method to enable visualization of an ASImageNode's image size. For app debugging purposes only. +* @param enabled Specify YES to turn on this debug feature when messaging the ASImageNode class. +*/ ++ (void)setImageDebugEnabled:(BOOL)enable; ++ (BOOL)shouldShowImageDebugOverlay; + +@end \ No newline at end of file diff --git a/AsyncDisplayKit/AsyncDisplayKit+Debug.m b/AsyncDisplayKit/AsyncDisplayKit+Debug.m new file mode 100644 index 0000000000..b8a0840d3b --- /dev/null +++ b/AsyncDisplayKit/AsyncDisplayKit+Debug.m @@ -0,0 +1,27 @@ +// +// AsyncDisplayKit+Debug.m +// AsyncDisplayKit +// +// Created by Hannah Troisi on 3/7/16. +// Copyright © 2016 Facebook. All rights reserved. +// + +#import "AsyncDisplayKit+Debug.h" +#import "ASDisplayNode+Subclasses.h" +#import "ASTextNode.h" + +static BOOL __enableImageSizeOverlay = NO; + +@implementation ASImageNode (Debug) + ++ (void)setImageDebugEnabled:(BOOL)enable; +{ + __enableImageSizeOverlay = enable; +} + ++ (BOOL)shouldShowImageDebugOverlay +{ + return __enableImageSizeOverlay; +} + +@end