From d1e6a650f028dc5c4d79c2a221e076041c9d1567 Mon Sep 17 00:00:00 2001 From: Hannah Troisi Date: Mon, 7 Mar 2016 09:44:16 -0800 Subject: [PATCH 1/2] [ASImageNode] A ASImageNode debug feature showing pixel scaling amount - shows a red text label overlay on bottom right hand corner of ASImageNodes with pixel scaling factor - import AsyncDisplayKit+Debug.h and enable using [ASImageNode setEnableImageDebugOverlay] --- AsyncDisplayKit/ASImageNode.mm | 47 +++++++++++++++++++++++-- AsyncDisplayKit/AsyncDisplayKit+Debug.h | 21 +++++++++++ AsyncDisplayKit/AsyncDisplayKit+Debug.m | 27 ++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 AsyncDisplayKit/AsyncDisplayKit+Debug.h create mode 100644 AsyncDisplayKit/AsyncDisplayKit+Debug.m 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 From fa15ab7babce23055e93b72fe4db9cd589ccd659 Mon Sep 17 00:00:00 2001 From: Hannah Troisi Date: Mon, 7 Mar 2016 09:44:16 -0800 Subject: [PATCH 2/2] [ASImageNode] A ASImageNode debug feature showing pixel scaling amount - shows a red text label overlay on bottom right hand corner of ASImageNodes with pixel scaling factor - import AsyncDisplayKit+Debug.h and enable using [ASImageNode setEnableImageDebugOverlay] --- AsyncDisplayKit.xcodeproj/project.pbxproj | 28 +++++++++++++++++++++++ AsyncDisplayKit/AsyncDisplayKit.h | 2 ++ 2 files changed, 30 insertions(+) diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 2d9f279763..9a4bd47da9 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -261,6 +261,10 @@ 69F10C861C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; 69F10C871C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6BDC61F61979037800E50D21 /* AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 764D83D41C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 764D83D21C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 764D83D51C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 764D83D21C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 764D83D61C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m in Sources */ = {isa = PBXBuildFile; fileRef = 764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m */; }; + 764D83D71C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m in Sources */ = {isa = PBXBuildFile; fileRef = 764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m */; }; 92DD2FE31BF4B97E0074C9DD /* ASMapNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 92DD2FE11BF4B97E0074C9DD /* ASMapNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 92DD2FE41BF4B97E0074C9DD /* ASMapNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 92DD2FE21BF4B97E0074C9DD /* ASMapNode.mm */; }; 92DD2FE61BF4D05E0074C9DD /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92DD2FE51BF4D05E0074C9DD /* MapKit.framework */; }; @@ -722,6 +726,8 @@ 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMainSerialQueue.mm; sourceTree = ""; }; 69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASRangeControllerUpdateRangeProtocol+Beta.h"; sourceTree = ""; }; 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; path = AsyncDisplayKit.h; sourceTree = ""; }; + 764D83D21C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AsyncDisplayKit+Debug.h"; sourceTree = ""; }; + 764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AsyncDisplayKit+Debug.m"; sourceTree = ""; }; 92DD2FE11BF4B97E0074C9DD /* ASMapNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMapNode.h; sourceTree = ""; }; 92DD2FE21BF4B97E0074C9DD /* ASMapNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMapNode.mm; sourceTree = ""; }; 92DD2FE51BF4D05E0074C9DD /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; @@ -1004,6 +1010,8 @@ ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */, ACC945AA1BA9E7C1005E1FB8 /* ASViewController.m */, 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */, + 764D83D21C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h */, + 764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m */, DB55C2651C641AE4004EDCF5 /* ASContextTransitioning.h */, 058D09E1195D050800B7D73C /* Details */, 058D0A01195D050800B7D73C /* Private */, @@ -1408,6 +1416,7 @@ 058D0A57195D05DC00B7D73C /* ASHighlightOverlayLayer.h in Headers */, 058D0A7C195D05F900B7D73C /* ASImageNode+CGExtras.h in Headers */, DBDB83941C6E879900D0098C /* ASPagerFlowLayout.h in Headers */, + 764D83D41C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h in Headers */, 058D0A4F195D05CB00B7D73C /* ASImageNode.h in Headers */, 05F20AA41A15733C00DCA68A /* ASImageProtocols.h in Headers */, 430E7C8F1B4C23F100697A4C /* ASIndexPath.h in Headers */, @@ -1582,6 +1591,7 @@ 9C49C3701B853961000B0DD5 /* ASStackLayoutable.h in Headers */, DE040EF91C2B40AC004692FF /* ASCollectionViewFlowLayoutInspector.h in Headers */, 34EFC7701B701CFA00AD841F /* ASStackLayoutDefines.h in Headers */, + 764D83D51C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h in Headers */, E5711A2C1C840C81009619D4 /* ASIndexedNodeContext.h in Headers */, 254C6B7B1BF94DF4003EC431 /* ASTextKitRenderer+Positioning.h in Headers */, CC7FD9E21BB603FF005CCB2B /* ASPhotosFrameworkImageRequest.h in Headers */, @@ -1655,6 +1665,7 @@ 058D09B9195D04C000B7D73C /* Frameworks */, 058D09BA195D04C000B7D73C /* Resources */, 3B9D88CDF51B429C8409E4B6 /* Copy Pods Resources */, + BD5CC779F736EBA28F5313FB /* Embed Pods Frameworks */, ); buildRules = ( ); @@ -1784,6 +1795,21 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; + BD5CC779F736EBA28F5313FB /* Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1832,6 +1858,7 @@ ACF6ED211B17843500DA7C62 /* ASDimension.mm in Sources */, 058D0A28195D050800B7D73C /* ASDisplayNode+AsyncDisplay.mm in Sources */, 058D0A29195D050800B7D73C /* ASDisplayNode+DebugTiming.mm in Sources */, + 764D83D61C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m in Sources */, 058D0A2A195D050800B7D73C /* ASDisplayNode+UIViewBridge.mm in Sources */, 25E327581C16819500A2170C /* ASPagerNode.m in Sources */, 058D0A14195D050800B7D73C /* ASDisplayNode.mm in Sources */, @@ -2006,6 +2033,7 @@ CC3B20861C3F76D600798563 /* ASPendingStateController.mm in Sources */, 254C6B8C1BF94F8A003EC431 /* ASTextKitTailTruncater.mm in Sources */, B35062051B010EFD0018CF92 /* ASMultiplexImageNode.mm in Sources */, + 764D83D71C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m in Sources */, B35062251B010EFD0018CF92 /* ASMutableAttributedStringBuilder.m in Sources */, B35062071B010EFD0018CF92 /* ASNetworkImageNode.mm in Sources */, 34EFC76D1B701CF100AD841F /* ASOverlayLayoutSpec.mm in Sources */, diff --git a/AsyncDisplayKit/AsyncDisplayKit.h b/AsyncDisplayKit/AsyncDisplayKit.h index 0a68a52462..fc345706c3 100644 --- a/AsyncDisplayKit/AsyncDisplayKit.h +++ b/AsyncDisplayKit/AsyncDisplayKit.h @@ -74,3 +74,5 @@ #import #import #import + +#import