Skip to content

Add Image resizeMode repeat on iOS #7968

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Examples/UIExplorer/ImageExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,18 @@ exports.examples = [
source={image}
/>
</View>
{ Platform.OS === 'ios' ?
<View style={styles.leftMargin}>
<Text style={[styles.resizeModeText]}>
Repeat
</Text>
<Image
style={styles.resizeMode}
resizeMode={Image.resizeMode.repeat}
source={image}
/>
</View>
: null }
{ Platform.OS === 'android' ?
<View style={styles.leftMargin}>
<Text style={[styles.resizeModeText]}>
Expand Down
5 changes: 4 additions & 1 deletion Libraries/Image/Image.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,11 @@ const Image = React.createClass({
*
* 'stretch': Scale width and height independently, This may change the
* aspect ratio of the src.
*
* 'repeat': Repeat the image to cover the frame of the view. The
* image will keep it's size and aspect ratio. (iOS only)
*/
resizeMode: PropTypes.oneOf(['cover', 'contain', 'stretch']),
resizeMode: PropTypes.oneOf(['cover', 'contain', 'stretch', 'repeat']),
/**
* A unique identifier for this element to be used in UI Automation
* testing scripts.
Expand Down
6 changes: 6 additions & 0 deletions Libraries/Image/ImageResizeMode.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ var ImageResizeMode = keyMirror({
* The image will not be scaled up.
*/
center: null,

/**
* repeat - The image will be repeated to cover the frame of the View. The
* image will keep it's size and aspect ratio.
*/
repeat: null,
});

module.exports = ImageResizeMode;
5 changes: 5 additions & 0 deletions Libraries/Image/RCTImageUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ CGRect RCTTargetRect(CGSize sourceSize, CGSize destSize,

switch (resizeMode) {
case RCTResizeModeStretch:
case RCTResizeModeRepeat:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure what these functions should return and what they are used for so maybe someone familiar with it could confirm that this is fine.


return (CGRect){CGPointZero, RCTCeilSize(destSize, destScale)};

Expand Down Expand Up @@ -204,6 +205,10 @@ BOOL RCTUpscalingRequired(CGSize sourceSize, CGFloat sourceScale,

return destSize.width > sourceSize.width;
}

case RCTResizeModeRepeat:

return NO;
}
}

Expand Down
1 change: 1 addition & 0 deletions Libraries/Image/RCTImageView.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
@property (nonatomic, assign) UIImageRenderingMode renderingMode;
@property (nonatomic, strong) RCTImageSource *source;
@property (nonatomic, assign) CGFloat blurRadius;
@property (nonatomic, assign) RCTResizeMode resizeMode;

@end
24 changes: 17 additions & 7 deletions Libraries/Image/RCTImageView.m
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,12 @@ - (void)updateImage
image = [image imageWithRenderingMode:_renderingMode];
}

// Applying capInsets of 0 will switch the "resizingMode" of the image to "tile" which is undesired
if (!UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, _capInsets)) {
if (_resizeMode == RCTResizeModeRepeat) {
image = [image resizableImageWithCapInsets:_capInsets resizingMode:UIImageResizingModeTile];
} else if (!UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, _capInsets)) {
// Applying capInsets of 0 will switch the "resizingMode" of the image to "tile" which is undesired
image = [image resizableImageWithCapInsets:_capInsets resizingMode:UIImageResizingModeStretch];
}

// Apply trilinear filtering to smooth out mis-sized images
self.layer.minificationFilter = kCAFilterTrilinear;
self.layer.magnificationFilter = kCAFilterTrilinear;
Expand Down Expand Up @@ -161,10 +162,19 @@ - (BOOL)sourceNeedsReload
return UIEdgeInsetsEqualToEdgeInsets(_capInsets, UIEdgeInsetsZero);
}

- (void)setContentMode:(UIViewContentMode)contentMode
- (void)setResizeMode:(RCTResizeMode)resizeMode
{
if (self.contentMode != contentMode) {
super.contentMode = contentMode;
if (_resizeMode != resizeMode) {
_resizeMode = resizeMode;

if (_resizeMode == RCTResizeModeRepeat) {
// Repeat resize mode is handled by the UIImage. Use scale to fill
// so the repeated image fills the UIImageView.
self.contentMode = UIViewContentModeScaleToFill;
} else {
self.contentMode = (UIViewContentMode)resizeMode;
}

if ([self sourceNeedsReload]) {
[self reloadImage];
}
Expand Down Expand Up @@ -229,7 +239,7 @@ - (void)reloadImage
size:imageSize
scale:imageScale
clipped:NO
resizeMode:(RCTResizeMode)self.contentMode
resizeMode:_resizeMode
progressBlock:progressHandler
completionBlock:^(NSError *error, UIImage *loadedImage) {

Expand Down
2 changes: 1 addition & 1 deletion Libraries/Image/RCTImageViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(onError, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onLoad, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onLoadEnd, RCTDirectEventBlock)
RCT_REMAP_VIEW_PROPERTY(resizeMode, contentMode, RCTResizeMode)
RCT_EXPORT_VIEW_PROPERTY(resizeMode, RCTResizeMode)
RCT_EXPORT_VIEW_PROPERTY(source, RCTImageSource)
RCT_CUSTOM_VIEW_PROPERTY(tintColor, UIColor, RCTImageView)
{
Expand Down
1 change: 1 addition & 0 deletions Libraries/Image/RCTResizeMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ typedef NS_ENUM(NSInteger, RCTResizeMode) {
RCTResizeModeCover = UIViewContentModeScaleAspectFill,
RCTResizeModeContain = UIViewContentModeScaleAspectFit,
RCTResizeModeStretch = UIViewContentModeScaleToFill,
RCTResizeModeRepeat = -1, // Use negative values to avoid conflicts with iOS enum values.
};

@interface RCTConvert(RCTResizeMode)
Expand Down
1 change: 1 addition & 0 deletions Libraries/Image/RCTResizeMode.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ @implementation RCTConvert(RCTResizeMode)
@"cover": @(RCTResizeModeCover),
@"contain": @(RCTResizeModeContain),
@"stretch": @(RCTResizeModeStretch),
@"repeat": @(RCTResizeModeRepeat),
}), RCTResizeModeStretch, integerValue)

@end