Intrinsic content size for network image sources of <Image>
Summary: It makes possible to just specify remote url for the <Image> and it will work. `<Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}} />` Reviewed By: javache Differential Revision: D5196055 fbshipit-source-id: aaf139c4518cc35d1f4cf810bbf0305aad73a55b
|
@ -81,6 +81,8 @@ static NSDictionary *onLoadParamsForSource(RCTImageSource *source)
|
|||
|
||||
// Whether the latest change of props requires the image to be reloaded
|
||||
BOOL _needsReload;
|
||||
|
||||
CGSize _intrinsicContentSize;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
|
@ -110,13 +112,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
|
||||
- (CGSize)intrinsicContentSize
|
||||
{
|
||||
// The first `imageSource` defines intrinsic content size.
|
||||
RCTImageSource *imageSource = _imageSources.firstObject;
|
||||
if (!imageSource) {
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
return imageSource.size;
|
||||
return _intrinsicContentSize;
|
||||
}
|
||||
|
||||
- (void)updateIntrinsicContentSize
|
||||
|
@ -193,6 +189,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
{
|
||||
if (![imageSources isEqual:_imageSources]) {
|
||||
_imageSources = [imageSources copy];
|
||||
|
||||
// If the first image source contains image size, use it to set up `_intrinsicContentSize`.
|
||||
// Otherwise we will update `_intrinsicContentSize` right after we have dowloaded image.
|
||||
// `_intrinsicContentSize` defaults to `{0, 0}` if `_imageSources` is empty.
|
||||
_intrinsicContentSize = _imageSources.firstObject.size;
|
||||
|
||||
[self updateIntrinsicContentSize];
|
||||
_needsReload = YES;
|
||||
}
|
||||
|
@ -250,11 +252,14 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
|
||||
- (RCTImageSource *)imageSourceForSize:(CGSize)size
|
||||
{
|
||||
if (![self hasMultipleSources]) {
|
||||
// If we have less than two sources of if we don't have intrinsic content size,
|
||||
// we have to return the first source.
|
||||
if (![self hasMultipleSources] ||
|
||||
CGSizeEqualToSize(_intrinsicContentSize, CGSizeZero)) {
|
||||
return _imageSources.firstObject;
|
||||
}
|
||||
|
||||
// Need to wait for layout pass before deciding.
|
||||
// Corner case for empty size.
|
||||
if (CGSizeEqualToSize(size, CGSizeZero)) {
|
||||
return nil;
|
||||
}
|
||||
|
@ -301,7 +306,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
RCTImageSource *source = [self imageSourceForSize:self.frame.size];
|
||||
_pendingImageSource = source;
|
||||
|
||||
if (source && self.frame.size.width > 0 && self.frame.size.height > 0) {
|
||||
if (source) {
|
||||
if (_onLoadStart) {
|
||||
_onLoadStart(nil);
|
||||
}
|
||||
|
@ -349,6 +354,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
|
||||
- (void)imageLoaderLoadedImage:(UIImage *)loadedImage error:(NSError *)error forImageSource:(RCTImageSource *)source partial:(BOOL)isPartialLoad
|
||||
{
|
||||
// Can be called from any queue.
|
||||
|
||||
if (![source isEqual:_pendingImageSource]) {
|
||||
// Bail out if source has changed since we started loading
|
||||
return;
|
||||
|
@ -365,8 +372,18 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
}
|
||||
|
||||
void (^setImageBlock)(UIImage *) = ^(UIImage *image) {
|
||||
RCTAssertMainQueue();
|
||||
|
||||
if (!isPartialLoad) {
|
||||
self->_imageSource = source;
|
||||
|
||||
if (CGSizeEqualToSize(self->_intrinsicContentSize, CGSizeZero) && [source isEqual:self->_imageSources.firstObject]) {
|
||||
// If we just downloaded an image from the first source and if we don't have `_intrinsicContentSize` yet,
|
||||
// use actual image size as `_intrinsicContentSize`.
|
||||
self->_intrinsicContentSize = image.size;
|
||||
[self updateIntrinsicContentSize];
|
||||
}
|
||||
|
||||
self->_pendingImageSource = nil;
|
||||
}
|
||||
|
||||
|
|
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 201 KiB |
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 164 KiB |
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 201 KiB |
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 201 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 161 KiB |
|
@ -641,10 +641,19 @@ exports.examples = [
|
|||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<Image source={require('./uie_thumb_big.png')} style={{alignSelf: 'center'}} />
|
||||
<Text>Plain static image without explicitly set size</Text>
|
||||
<Image
|
||||
source={require('./uie_thumb_big.png')}
|
||||
style={{alignSelf: 'center'}}
|
||||
/>
|
||||
<Text>Plain network image without explicitly set size</Text>
|
||||
<Image
|
||||
source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
platform: 'ios',
|
||||
},
|
||||
{
|
||||
title: 'MultipleSourcesExample',
|
||||
|
|