From d5943b0e47428fda78121a5b51c7a40a646af865 Mon Sep 17 00:00:00 2001 From: James Ide Date: Mon, 13 Jul 2015 10:30:34 -0700 Subject: [PATCH] [Image] Add support for tintColor to remote images Summary: Remote images now support the `tintColor` prop. Also picked nicer demo colors for the UIExplorer example. Fixes #1867 Closes https://github.com/facebook/react-native/pull/1932 Github Author: James Ide --- Examples/UIExplorer/ImageExample.js | 60 ++++++++++++++------ Libraries/Image/RCTImageDownloader.h | 1 + Libraries/Image/RCTImageDownloader.m | 5 ++ Libraries/Image/RCTNetworkImageView.h | 5 ++ Libraries/Image/RCTNetworkImageView.m | 17 +++++- Libraries/Image/RCTNetworkImageViewManager.m | 10 ++++ 6 files changed, 78 insertions(+), 20 deletions(-) diff --git a/Examples/UIExplorer/ImageExample.js b/Examples/UIExplorer/ImageExample.js index 60a4a5ab1..faa3267a1 100644 --- a/Examples/UIExplorer/ImageExample.js +++ b/Examples/UIExplorer/ImageExample.js @@ -194,23 +194,46 @@ exports.examples = [ 'pixels to the tint color.', render: function() { return ( - - - - - + + + + + + + + + It also works with downloaded images: + + + + + + + ); }, @@ -283,6 +306,9 @@ var styles = StyleSheet.create({ background: { backgroundColor: '#222222' }, + sectionText: { + marginVertical: 6, + }, nestedText: { marginLeft: 12, marginTop: 20, diff --git a/Libraries/Image/RCTImageDownloader.h b/Libraries/Image/RCTImageDownloader.h index 44b2b7369..43bb9a69d 100644 --- a/Libraries/Image/RCTImageDownloader.h +++ b/Libraries/Image/RCTImageDownloader.h @@ -38,6 +38,7 @@ typedef void (^RCTImageDownloadCancellationBlock)(void); size:(CGSize)size scale:(CGFloat)scale resizeMode:(UIViewContentMode)resizeMode + tintColor:(UIColor *)tintColor backgroundColor:(UIColor *)backgroundColor progressBlock:(RCTDataProgressBlock)progressBlock block:(RCTImageDownloadBlock)block; diff --git a/Libraries/Image/RCTImageDownloader.m b/Libraries/Image/RCTImageDownloader.m index a9af87b22..0f9cad198 100644 --- a/Libraries/Image/RCTImageDownloader.m +++ b/Libraries/Image/RCTImageDownloader.m @@ -131,6 +131,7 @@ CGRect RCTClipRect(CGSize, CGFloat, CGSize, CGFloat, UIViewContentMode); size:(CGSize)size scale:(CGFloat)scale resizeMode:(UIViewContentMode)resizeMode + tintColor:(UIColor *)tintColor backgroundColor:(UIColor *)backgroundColor progressBlock:(RCTDataProgressBlock)progressBlock block:(RCTImageDownloadBlock)block @@ -173,6 +174,10 @@ CGRect RCTClipRect(CGSize, CGFloat, CGSize, CGFloat, UIViewContentMode); [blendColor setFill]; UIRectFill((CGRect){CGPointZero, destSize}); } + if (tintColor) { + image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + [tintColor setFill]; + } [image drawInRect:imageRect]; image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); diff --git a/Libraries/Image/RCTNetworkImageView.h b/Libraries/Image/RCTNetworkImageView.h index 6cdf31216..6dd73e9aa 100644 --- a/Libraries/Image/RCTNetworkImageView.h +++ b/Libraries/Image/RCTNetworkImageView.h @@ -28,6 +28,11 @@ */ @property (nonatomic, strong) NSURL *imageURL; +/** + * Whether the image should be masked with this view's tint color. + */ +@property (nonatomic, assign) BOOL tinted; + /** * By default, changing imageURL will reset whatever existing image was present * and revert to defaultImage while the new image loads. In certain obscure cases you diff --git a/Libraries/Image/RCTNetworkImageView.m b/Libraries/Image/RCTNetworkImageView.m index 8c6748f76..f8dc28157 100644 --- a/Libraries/Image/RCTNetworkImageView.m +++ b/Libraries/Image/RCTNetworkImageView.m @@ -60,6 +60,12 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder) [self _updateImage]; } +- (void)setTintColor:(UIColor *)tintColor +{ + super.tintColor = tintColor; + [self _updateImage]; +} + - (void)setProgressHandlerRegistered:(BOOL)progressHandlerRegistered { _progressHandlerRegistered = progressHandlerRegistered; @@ -144,9 +150,14 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder) } }]; } else { - _downloadToken = [_imageDownloader downloadImageForURL:imageURL size:self.bounds.size scale:RCTScreenScale() - resizeMode:self.contentMode backgroundColor:self.backgroundColor - progressBlock:progressHandler block:^(UIImage *image, NSError *error) { + _downloadToken = [_imageDownloader downloadImageForURL:imageURL + size:self.bounds.size + scale:RCTScreenScale() + resizeMode:self.contentMode + tintColor:_tinted ? self.tintColor : nil + backgroundColor:self.backgroundColor + progressBlock:progressHandler + block:^(UIImage *image, NSError *error) { if (image) { dispatch_async(dispatch_get_main_queue(), ^{ if (imageURL != self.imageURL) { diff --git a/Libraries/Image/RCTNetworkImageViewManager.m b/Libraries/Image/RCTNetworkImageViewManager.m index 706496e34..29d990b27 100644 --- a/Libraries/Image/RCTNetworkImageViewManager.m +++ b/Libraries/Image/RCTNetworkImageViewManager.m @@ -31,6 +31,16 @@ RCT_REMAP_VIEW_PROPERTY(defaultImageSrc, defaultImage, UIImage) RCT_REMAP_VIEW_PROPERTY(src, imageURL, NSURL) RCT_REMAP_VIEW_PROPERTY(resizeMode, contentMode, UIViewContentMode) RCT_EXPORT_VIEW_PROPERTY(progressHandlerRegistered, BOOL) +RCT_CUSTOM_VIEW_PROPERTY(tintColor, UIColor, RCTNetworkImageView) +{ + if (json) { + view.tinted = YES; + view.tintColor = [RCTConvert UIColor:json]; + } else { + view.tinted = defaultView.tinted; + view.tintColor = defaultView.tintColor; + } +} - (NSDictionary *)customDirectEventTypes {