diff --git a/AsyncDisplayKit/ASImageNode.h b/AsyncDisplayKit/ASImageNode.h index fcabb95d50..37b3a5c4ef 100644 --- a/AsyncDisplayKit/ASImageNode.h +++ b/AsyncDisplayKit/ASImageNode.h @@ -12,6 +12,9 @@ typedef NS_ENUM(NSUInteger, ASImageNodeTint) { ASImageNodeTintNormal = 0, ASImageNodeTintGreyscale, }; + +typedef UIImage *(^asimagenode_modification_block_t)(UIImage *); + // FIXME: This class should not derive from ASControlNode once ASButtonNode is implemented. @interface ASImageNode : ASControlNode @@ -40,6 +43,11 @@ typedef NS_ENUM(NSUInteger, ASImageNodeTint) { */ @property (nonatomic, readwrite, assign) CGRect cropRect; +/** + @abstract An optional block which can perform drawing operations on {@ref image} during the display phase. + @discussion Can be used to add image effects (such as rounding, adding borders, or other pattern overlays) without extraneous display calls. + */ +@property (nonatomic, readwrite, copy) asimagenode_modification_block_t imageModificationBlock; #pragma mark - /** diff --git a/AsyncDisplayKit/ASImageNode.mm b/AsyncDisplayKit/ASImageNode.mm index 622aa9ca0f..a5c3da6a6c 100644 --- a/AsyncDisplayKit/ASImageNode.mm +++ b/AsyncDisplayKit/ASImageNode.mm @@ -26,13 +26,14 @@ @property (nonatomic, retain) UIColor *backgroundColor; @property (nonatomic, assign) UIViewContentMode contentMode; @property (nonatomic, assign) CGRect cropRect; +@property (nonatomic, copy) asimagenode_modification_block_t imageModificationBlock; @end // TODO: eliminate explicit parameters with a set of keys copied from the node @implementation _ASImageNodeDrawParameters -- (id)initWithCrop:(BOOL)cropEnabled opaque:(BOOL)opaque image:(UIImage *)image bounds:(CGRect)bounds contentsScale:(CGFloat)contentsScale backgroundColor:(UIColor *)backgroundColor tint:(ASImageNodeTint)tint contentMode:(UIViewContentMode)contentMode cropRect:(CGRect)cropRect +- (id)initWithCrop:(BOOL)cropEnabled opaque:(BOOL)opaque image:(UIImage *)image bounds:(CGRect)bounds contentsScale:(CGFloat)contentsScale backgroundColor:(UIColor *)backgroundColor tint:(ASImageNodeTint)tint contentMode:(UIViewContentMode)contentMode cropRect:(CGRect)cropRect imageModificationBlock:(asimagenode_modification_block_t)imageModificationBlock { self = [self init]; if (!self) return nil; @@ -46,6 +47,7 @@ _tint = tint; _contentMode = contentMode; _cropRect = cropRect; + _imageModificationBlock = [imageModificationBlock copy]; return self; } @@ -54,6 +56,7 @@ { [_image release]; [_backgroundColor release]; + [_imageModificationBlock release]; [super dealloc]; } @@ -103,6 +106,7 @@ { [_displayCompletionBlock release]; [_image release]; + [_imageModificationBlock release]; [super dealloc]; } @@ -163,7 +167,9 @@ backgroundColor:self.backgroundColor tint:self.tint contentMode:self.contentMode - cropRect:self.cropRect] autorelease]; + cropRect:self.cropRect + imageModificationBlock:self.imageModificationBlock + ] autorelease]; } + (UIImage *)displayWithParameters:(_ASImageNodeDrawParameters *)parameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelled @@ -247,6 +253,10 @@ UIGraphicsEndImageContext(); + if (parameters.imageModificationBlock != NULL) { + result = parameters.imageModificationBlock(result); + } + if (stretchable) { return [image resizableImageWithCapInsets:image.capInsets resizingMode:image.resizingMode]; }