Skip to content

Commit 66a2940

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
Add border properties to RCTImageView
Summary: `RCTImageView` is now a subclass of `RCTView` and includes `UIImageView` as it's subview. This enables the use of `borderRadius`, `borderWidth`, `borderColor` properties and all of their derivatives. Possible problem: Now `RCTImageView` is backed by two views (`RCTView` + `UIImageView`), not a single one. That's 4 `CALayers`. Possible workaround would be to insert the image directly into `self.layer.contents`. Reviewed By: RSNara Differential Revision: D14875673 fbshipit-source-id: 594b2cd1ddffc6627566e07983c6d8f0b37dc2bb
1 parent 65033d7 commit 66a2940

File tree

2 files changed

+32
-19
lines changed

2 files changed

+32
-19
lines changed

Libraries/Image/RCTImageView.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
*/
77

88
#import <UIKit/UIKit.h>
9-
9+
#import <React/RCTView.h>
1010
#import <React/RCTResizeMode.h>
1111

1212
@class RCTBridge;
1313
@class RCTImageSource;
1414

15-
@interface RCTImageView : UIImageView
15+
@interface RCTImageView : RCTView
1616

1717
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
1818

Libraries/Image/RCTImageView.m

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,13 @@ @implementation RCTImageView
7878

7979
// Whether the latest change of props requires the image to be reloaded
8080
BOOL _needsReload;
81+
82+
UIImageView *_imageView;
8183
}
8284

8385
- (instancetype)initWithBridge:(RCTBridge *)bridge
8486
{
85-
if ((self = [super init])) {
87+
if ((self = [super initWithFrame:CGRectZero])) {
8688
_bridge = bridge;
8789

8890
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
@@ -94,6 +96,8 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
9496
selector:@selector(clearImageIfDetached)
9597
name:UIApplicationDidEnterBackgroundNotification
9698
object:nil];
99+
_imageView = [[UIImageView alloc] init];
100+
[self addSubview:_imageView];
97101
}
98102
return self;
99103
}
@@ -105,10 +109,14 @@ - (void)dealloc
105109

106110
RCT_NOT_IMPLEMENTED(- (instancetype)init)
107111

112+
RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
113+
114+
RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
115+
108116
- (void)updateWithImage:(UIImage *)image
109117
{
110118
if (!image) {
111-
super.image = nil;
119+
_imageView.image = nil;
112120
return;
113121
}
114122

@@ -125,16 +133,16 @@ - (void)updateWithImage:(UIImage *)image
125133
}
126134

127135
// Apply trilinear filtering to smooth out mis-sized images
128-
self.layer.minificationFilter = kCAFilterTrilinear;
129-
self.layer.magnificationFilter = kCAFilterTrilinear;
136+
_imageView.layer.minificationFilter = kCAFilterTrilinear;
137+
_imageView.layer.magnificationFilter = kCAFilterTrilinear;
130138

131-
super.image = image;
139+
_imageView.image = image;
132140
}
133141

134142
- (void)setImage:(UIImage *)image
135143
{
136144
image = image ?: _defaultImage;
137-
if (image != self.image) {
145+
if (image != _imageView.image) {
138146
[self updateWithImage:image];
139147
}
140148
}
@@ -157,7 +165,7 @@ - (void)setCapInsets:(UIEdgeInsets)capInsets
157165
_needsReload = YES;
158166
} else {
159167
_capInsets = capInsets;
160-
[self updateWithImage:self.image];
168+
[self updateWithImage:_imageView.image];
161169
}
162170
}
163171
}
@@ -166,7 +174,7 @@ - (void)setRenderingMode:(UIImageRenderingMode)renderingMode
166174
{
167175
if (_renderingMode != renderingMode) {
168176
_renderingMode = renderingMode;
169-
[self updateWithImage:self.image];
177+
[self updateWithImage:_imageView.image];
170178
}
171179
}
172180

@@ -186,9 +194,9 @@ - (void)setResizeMode:(RCTResizeMode)resizeMode
186194
if (_resizeMode == RCTResizeModeRepeat) {
187195
// Repeat resize mode is handled by the UIImage. Use scale to fill
188196
// so the repeated image fills the UIImageView.
189-
self.contentMode = UIViewContentModeScaleToFill;
197+
_imageView.contentMode = UIViewContentModeScaleToFill;
190198
} else {
191-
self.contentMode = (UIViewContentMode)resizeMode;
199+
_imageView.contentMode = (UIViewContentMode)resizeMode;
192200
}
193201

194202
if ([self shouldReloadImageSourceAfterResize]) {
@@ -211,8 +219,8 @@ - (void)cancelImageLoad
211219
- (void)clearImage
212220
{
213221
[self cancelImageLoad];
214-
[self.layer removeAnimationForKey:@"contents"];
215-
self.image = nil;
222+
[_imageView.layer removeAnimationForKey:@"contents"];
223+
_imageView.image = nil;
216224
_imageSource = nil;
217225
}
218226

@@ -351,10 +359,10 @@ - (void)imageLoaderLoadedImage:(UIImage *)loadedImage error:(NSError *)error for
351359
}
352360

353361
if (image.reactKeyframeAnimation) {
354-
[self.layer addAnimation:image.reactKeyframeAnimation forKey:@"contents"];
362+
[self->_imageView.layer addAnimation:image.reactKeyframeAnimation forKey:@"contents"];
355363
} else {
356-
[self.layer removeAnimationForKey:@"contents"];
357-
self.image = image;
364+
[self->_imageView.layer removeAnimationForKey:@"contents"];
365+
self->_imageView.image = image;
358366
}
359367

360368
if (isPartialLoad) {
@@ -401,8 +409,8 @@ - (void)reactSetFrame:(CGRect)frame
401409
_targetSize = frame.size;
402410
[self reloadImage];
403411
} else if ([self shouldReloadImageSourceAfterResize]) {
404-
CGSize imageSize = self.image.size;
405-
CGFloat imageScale = self.image.scale;
412+
CGSize imageSize = _imageView.image.size;
413+
CGFloat imageScale = _imageView.image.scale;
406414
CGSize idealSize = RCTTargetSize(imageSize, imageScale, frame.size, RCTScreenScale(),
407415
(RCTResizeMode)self.contentMode, YES);
408416

@@ -450,4 +458,9 @@ - (void)didMoveToWindow
450458
}
451459
}
452460

461+
- (void)layoutSubviews {
462+
[super layoutSubviews];
463+
_imageView.frame = self.bounds;
464+
}
465+
453466
@end

0 commit comments

Comments
 (0)