Implemented inline image support for <Text>
Summary: @public This diff implements inline image support for <Text> nodes. Images are specified using <Image> tags, however all properties of the image are currently ignored apart from the source (including width/height styles). Images are loaded asyncronously, and will trigger a text re-layout when they have loaded. Reviewed By: @javache Differential Revision: D2507725 fb-gh-sync-id: 59d0696d00a1bc531915cc35242a16b2dec96e85
This commit is contained in:
parent
c740edaf03
commit
91e6c98ecd
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
var React = require('react-native');
|
var React = require('react-native');
|
||||||
var {
|
var {
|
||||||
|
Image,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Text,
|
Text,
|
||||||
View,
|
View,
|
||||||
|
@ -397,6 +398,17 @@ exports.examples = [
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
}, {
|
||||||
|
title: 'Inline images',
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text>
|
||||||
|
This text contains an inline image <Image source={require('./flux.png')}/>. Neat, huh?
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
},
|
||||||
}];
|
}];
|
||||||
|
|
||||||
var styles = StyleSheet.create({
|
var styles = StyleSheet.create({
|
||||||
|
|
|
@ -153,6 +153,10 @@ var Image = React.createClass({
|
||||||
validAttributes: ReactNativeViewAttributes.UIView
|
validAttributes: ReactNativeViewAttributes.UIView
|
||||||
},
|
},
|
||||||
|
|
||||||
|
contextTypes: {
|
||||||
|
isInAParentText: React.PropTypes.bool
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
for (var prop in cfg.nativeOnly) {
|
for (var prop in cfg.nativeOnly) {
|
||||||
if (this.props[prop] !== undefined) {
|
if (this.props[prop] !== undefined) {
|
||||||
|
@ -182,6 +186,9 @@ var Image = React.createClass({
|
||||||
RawImage = RCTImageView;
|
RawImage = RCTImageView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.context.isInAParentText) {
|
||||||
|
return <RCTVirtualImage source={source}/>;
|
||||||
|
} else {
|
||||||
return (
|
return (
|
||||||
<RawImage
|
<RawImage
|
||||||
{...this.props}
|
{...this.props}
|
||||||
|
@ -193,6 +200,7 @@ var Image = React.createClass({
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var styles = StyleSheet.create({
|
var styles = StyleSheet.create({
|
||||||
|
@ -210,6 +218,7 @@ var cfg = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
var RCTImageView = requireNativeComponent('RCTImageView', Image, cfg);
|
var RCTImageView = requireNativeComponent('RCTImageView', Image, cfg);
|
||||||
var RCTNetworkImageView = (NativeModules.NetworkImageViewManager) ? requireNativeComponent('RCTNetworkImageView', Image, cfg) : RCTImageView;
|
var RCTNetworkImageView = NativeModules.NetworkImageViewManager ? requireNativeComponent('RCTNetworkImageView', Image, cfg) : RCTImageView;
|
||||||
|
var RCTVirtualImage = requireNativeComponent('RCTVirtualImage', Image);
|
||||||
|
|
||||||
module.exports = Image;
|
module.exports = Image;
|
||||||
|
|
|
@ -48,7 +48,7 @@ RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSource, i, NULL);
|
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSource, i, NULL);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
image = [UIImage imageWithCGImage:imageRef];
|
image = [UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSDictionary *frameProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(imageSource, i, NULL);
|
NSDictionary *frameProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(imageSource, i, NULL);
|
||||||
|
@ -98,7 +98,7 @@ RCT_EXPORT_MODULE()
|
||||||
// Don't bother creating an animation
|
// Don't bother creating an animation
|
||||||
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
|
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
|
||||||
if (imageRef) {
|
if (imageRef) {
|
||||||
image = [UIImage imageWithCGImage:imageRef];
|
image = [UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp];
|
||||||
CFRelease(imageRef);
|
CFRelease(imageRef);
|
||||||
}
|
}
|
||||||
CFRelease(imageSource);
|
CFRelease(imageSource);
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
1304D5AC1AA8C4A30002E2BE /* RCTImageViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5AA1AA8C4A30002E2BE /* RCTImageViewManager.m */; };
|
1304D5AC1AA8C4A30002E2BE /* RCTImageViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5AA1AA8C4A30002E2BE /* RCTImageViewManager.m */; };
|
||||||
1304D5B21AA8C50D0002E2BE /* RCTGIFImageDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5B11AA8C50D0002E2BE /* RCTGIFImageDecoder.m */; };
|
1304D5B21AA8C50D0002E2BE /* RCTGIFImageDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5B11AA8C50D0002E2BE /* RCTGIFImageDecoder.m */; };
|
||||||
134B00A21B54232B00EC8DFB /* RCTImageUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 134B00A11B54232B00EC8DFB /* RCTImageUtils.m */; };
|
134B00A21B54232B00EC8DFB /* RCTImageUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 134B00A11B54232B00EC8DFB /* RCTImageUtils.m */; };
|
||||||
|
13EF7F0B1BC42D4E003F47DD /* RCTShadowVirtualImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 13EF7F081BC42D4E003F47DD /* RCTShadowVirtualImage.m */; settings = {ASSET_TAGS = (); }; };
|
||||||
|
13EF7F0C1BC42D4E003F47DD /* RCTVirtualImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13EF7F0A1BC42D4E003F47DD /* RCTVirtualImageManager.m */; settings = {ASSET_TAGS = (); }; };
|
||||||
143879381AAD32A300F088A5 /* RCTImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 143879371AAD32A300F088A5 /* RCTImageLoader.m */; };
|
143879381AAD32A300F088A5 /* RCTImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 143879371AAD32A300F088A5 /* RCTImageLoader.m */; };
|
||||||
35123E6B1B59C99D00EBAD80 /* RCTImageStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 35123E6A1B59C99D00EBAD80 /* RCTImageStoreManager.m */; };
|
35123E6B1B59C99D00EBAD80 /* RCTImageStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 35123E6A1B59C99D00EBAD80 /* RCTImageStoreManager.m */; };
|
||||||
354631681B69857700AA0B86 /* RCTImageEditingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 354631671B69857700AA0B86 /* RCTImageEditingManager.m */; };
|
354631681B69857700AA0B86 /* RCTImageEditingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 354631671B69857700AA0B86 /* RCTImageEditingManager.m */; };
|
||||||
|
@ -39,6 +41,10 @@
|
||||||
1304D5B11AA8C50D0002E2BE /* RCTGIFImageDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTGIFImageDecoder.m; sourceTree = "<group>"; };
|
1304D5B11AA8C50D0002E2BE /* RCTGIFImageDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTGIFImageDecoder.m; sourceTree = "<group>"; };
|
||||||
134B00A01B54232B00EC8DFB /* RCTImageUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageUtils.h; sourceTree = "<group>"; };
|
134B00A01B54232B00EC8DFB /* RCTImageUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageUtils.h; sourceTree = "<group>"; };
|
||||||
134B00A11B54232B00EC8DFB /* RCTImageUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageUtils.m; sourceTree = "<group>"; };
|
134B00A11B54232B00EC8DFB /* RCTImageUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageUtils.m; sourceTree = "<group>"; };
|
||||||
|
13EF7F071BC42D4E003F47DD /* RCTShadowVirtualImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTShadowVirtualImage.h; sourceTree = "<group>"; };
|
||||||
|
13EF7F081BC42D4E003F47DD /* RCTShadowVirtualImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTShadowVirtualImage.m; sourceTree = "<group>"; };
|
||||||
|
13EF7F091BC42D4E003F47DD /* RCTVirtualImageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTVirtualImageManager.h; sourceTree = "<group>"; };
|
||||||
|
13EF7F0A1BC42D4E003F47DD /* RCTVirtualImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTVirtualImageManager.m; sourceTree = "<group>"; };
|
||||||
143879361AAD32A300F088A5 /* RCTImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageLoader.h; sourceTree = "<group>"; };
|
143879361AAD32A300F088A5 /* RCTImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageLoader.h; sourceTree = "<group>"; };
|
||||||
143879371AAD32A300F088A5 /* RCTImageLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageLoader.m; sourceTree = "<group>"; };
|
143879371AAD32A300F088A5 /* RCTImageLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageLoader.m; sourceTree = "<group>"; };
|
||||||
35123E691B59C99D00EBAD80 /* RCTImageStoreManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageStoreManager.h; sourceTree = "<group>"; };
|
35123E691B59C99D00EBAD80 /* RCTImageStoreManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageStoreManager.h; sourceTree = "<group>"; };
|
||||||
|
@ -84,6 +90,10 @@
|
||||||
35123E6A1B59C99D00EBAD80 /* RCTImageStoreManager.m */,
|
35123E6A1B59C99D00EBAD80 /* RCTImageStoreManager.m */,
|
||||||
134B00A01B54232B00EC8DFB /* RCTImageUtils.h */,
|
134B00A01B54232B00EC8DFB /* RCTImageUtils.h */,
|
||||||
134B00A11B54232B00EC8DFB /* RCTImageUtils.m */,
|
134B00A11B54232B00EC8DFB /* RCTImageUtils.m */,
|
||||||
|
13EF7F071BC42D4E003F47DD /* RCTShadowVirtualImage.h */,
|
||||||
|
13EF7F081BC42D4E003F47DD /* RCTShadowVirtualImage.m */,
|
||||||
|
13EF7F091BC42D4E003F47DD /* RCTVirtualImageManager.h */,
|
||||||
|
13EF7F0A1BC42D4E003F47DD /* RCTVirtualImageManager.m */,
|
||||||
58B5115E1A9E6B3D00147676 /* Products */,
|
58B5115E1A9E6B3D00147676 /* Products */,
|
||||||
);
|
);
|
||||||
indentWidth = 2;
|
indentWidth = 2;
|
||||||
|
@ -154,6 +164,7 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
13EF7F0C1BC42D4E003F47DD /* RCTVirtualImageManager.m in Sources */,
|
||||||
35123E6B1B59C99D00EBAD80 /* RCTImageStoreManager.m in Sources */,
|
35123E6B1B59C99D00EBAD80 /* RCTImageStoreManager.m in Sources */,
|
||||||
58B5118F1A9E6BD600147676 /* RCTImageDownloader.m in Sources */,
|
58B5118F1A9E6BD600147676 /* RCTImageDownloader.m in Sources */,
|
||||||
1304D5AC1AA8C4A30002E2BE /* RCTImageViewManager.m in Sources */,
|
1304D5AC1AA8C4A30002E2BE /* RCTImageViewManager.m in Sources */,
|
||||||
|
@ -161,6 +172,7 @@
|
||||||
143879381AAD32A300F088A5 /* RCTImageLoader.m in Sources */,
|
143879381AAD32A300F088A5 /* RCTImageLoader.m in Sources */,
|
||||||
354631681B69857700AA0B86 /* RCTImageEditingManager.m in Sources */,
|
354631681B69857700AA0B86 /* RCTImageEditingManager.m in Sources */,
|
||||||
1304D5AB1AA8C4A30002E2BE /* RCTImageView.m in Sources */,
|
1304D5AB1AA8C4A30002E2BE /* RCTImageView.m in Sources */,
|
||||||
|
13EF7F0B1BC42D4E003F47DD /* RCTShadowVirtualImage.m in Sources */,
|
||||||
134B00A21B54232B00EC8DFB /* RCTImageUtils.m in Sources */,
|
134B00A21B54232B00EC8DFB /* RCTImageUtils.m in Sources */,
|
||||||
83DDA1571B8DCA5800892A1C /* RCTAssetBundleImageLoader.m in Sources */,
|
83DDA1571B8DCA5800892A1C /* RCTAssetBundleImageLoader.m in Sources */,
|
||||||
);
|
);
|
||||||
|
|
|
@ -135,7 +135,7 @@ RCT_EXPORT_MODULE()
|
||||||
// Normally -dataWithContentsOfURL: would be bad but this is a data URL.
|
// Normally -dataWithContentsOfURL: would be bad but this is a data URL.
|
||||||
NSData *data = [NSData dataWithContentsOfURL:imageURL];
|
NSData *data = [NSData dataWithContentsOfURL:imageURL];
|
||||||
|
|
||||||
UIImage *image = [UIImage imageWithData:data];
|
UIImage *image = [UIImage imageWithData:data scale:scale];
|
||||||
if (image) {
|
if (image) {
|
||||||
if (progressHandler) {
|
if (progressHandler) {
|
||||||
progressHandler(1, 1);
|
progressHandler(1, 1);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#import "RCTConvert.h"
|
#import "RCTConvert.h"
|
||||||
#import "RCTDefines.h"
|
#import "RCTDefines.h"
|
||||||
#import "RCTImageDownloader.h"
|
#import "RCTImageDownloader.h"
|
||||||
|
#import "RCTImageUtils.h"
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
#import "RCTUtils.h"
|
#import "RCTUtils.h"
|
||||||
|
|
||||||
|
@ -165,7 +166,7 @@ RCT_EXPORT_MODULE()
|
||||||
}];
|
}];
|
||||||
} else {
|
} else {
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
UIImage *image = [UIImage imageWithData:data];
|
UIImage *image = [UIImage imageWithData:data scale:scale];
|
||||||
if (image) {
|
if (image) {
|
||||||
RCTDispatchCallbackOnMainQueue(completionBlock, nil, image);
|
RCTDispatchCallbackOnMainQueue(completionBlock, nil, image);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,10 +8,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
#import "RCTImageComponent.h"
|
||||||
|
|
||||||
@class RCTBridge;
|
@class RCTBridge;
|
||||||
|
|
||||||
@interface RCTImageView : UIImageView
|
@interface RCTImageView : UIImageView <RCTImageComponent>
|
||||||
|
|
||||||
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
* Determines whether an image of `currentSize` should be reloaded for display
|
* Determines whether an image of `currentSize` should be reloaded for display
|
||||||
* at `idealSize`.
|
* at `idealSize`.
|
||||||
*/
|
*/
|
||||||
static BOOL RCTShouldReloadImageForSizeChange(CGSize currentSize, CGSize idealSize) {
|
static BOOL RCTShouldReloadImageForSizeChange(CGSize currentSize, CGSize idealSize)
|
||||||
|
{
|
||||||
static const CGFloat upscaleThreshold = 1.2;
|
static const CGFloat upscaleThreshold = 1.2;
|
||||||
static const CGFloat downscaleThreshold = 0.5;
|
static const CGFloat downscaleThreshold = 0.5;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "RCTShadowView.h"
|
||||||
|
#import "RCTImageComponent.h"
|
||||||
|
|
||||||
|
@class RCTBridge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shadow image component, used for embedding images in non-view contexts such
|
||||||
|
* as text. This is NOT used for ordinary <Image> views.
|
||||||
|
*/
|
||||||
|
@interface RCTShadowVirtualImage : RCTShadowView <RCTImageComponent>
|
||||||
|
|
||||||
|
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
||||||
|
|
||||||
|
@property (nonatomic, copy) NSDictionary *source;
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "RCTShadowVirtualImage.h"
|
||||||
|
#import "RCTImageLoader.h"
|
||||||
|
#import "RCTBridge.h"
|
||||||
|
#import "RCTConvert.h"
|
||||||
|
|
||||||
|
@implementation RCTShadowVirtualImage
|
||||||
|
{
|
||||||
|
RCTBridge *_bridge;
|
||||||
|
}
|
||||||
|
|
||||||
|
@synthesize image = _image;
|
||||||
|
|
||||||
|
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||||
|
{
|
||||||
|
if ((self = [super init])) {
|
||||||
|
_bridge = bridge;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||||
|
|
||||||
|
- (void)setSource:(NSDictionary *)source
|
||||||
|
{
|
||||||
|
if (![source isEqual:_source]) {
|
||||||
|
_source = [source copy];
|
||||||
|
NSString *imageTag = [RCTConvert NSString:_source[@"uri"]];
|
||||||
|
CGFloat scale = [RCTConvert CGFloat:_source[@"scale"]] ?: 1;
|
||||||
|
|
||||||
|
__weak RCTShadowVirtualImage *weakSelf = self;
|
||||||
|
[_bridge.imageLoader loadImageWithTag:imageTag size:CGSizeZero scale:scale resizeMode:UIViewContentModeScaleToFill progressBlock:nil completionBlock:^(NSError *error, UIImage *image) {
|
||||||
|
RCTShadowVirtualImage *strongSelf = weakSelf;
|
||||||
|
strongSelf->_image = image;
|
||||||
|
[strongSelf dirtyText];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "RCTViewManager.h"
|
||||||
|
|
||||||
|
@interface RCTVirtualImageManager : RCTViewManager
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,24 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "RCTVirtualImageManager.h"
|
||||||
|
#import "RCTShadowVirtualImage.h"
|
||||||
|
|
||||||
|
@implementation RCTVirtualImageManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
|
- (RCTShadowView *)shadowView
|
||||||
|
{
|
||||||
|
return [[RCTShadowVirtualImage alloc] initWithBridge:self.bridge];
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_SHADOW_PROPERTY(source, NSDictionary)
|
||||||
|
|
||||||
|
@end
|
|
@ -13,6 +13,7 @@
|
||||||
#import "RCTUIManager.h"
|
#import "RCTUIManager.h"
|
||||||
#import "RCTBridge.h"
|
#import "RCTBridge.h"
|
||||||
#import "RCTConvert.h"
|
#import "RCTConvert.h"
|
||||||
|
#import "RCTImageComponent.h"
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
#import "RCTShadowRawText.h"
|
#import "RCTShadowRawText.h"
|
||||||
#import "RCTSparseArray.h"
|
#import "RCTSparseArray.h"
|
||||||
|
@ -191,8 +192,17 @@ static css_dim_t RCTMeasure(void *context, float width)
|
||||||
} else if ([child isKindOfClass:[RCTShadowRawText class]]) {
|
} else if ([child isKindOfClass:[RCTShadowRawText class]]) {
|
||||||
RCTShadowRawText *shadowRawText = (RCTShadowRawText *)child;
|
RCTShadowRawText *shadowRawText = (RCTShadowRawText *)child;
|
||||||
[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:shadowRawText.text ?: @""]];
|
[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:shadowRawText.text ?: @""]];
|
||||||
|
} else if ([child conformsToProtocol:@protocol(RCTImageComponent)]) {
|
||||||
|
UIImage *image = ((id<RCTImageComponent>)child).image;
|
||||||
|
if (image) {
|
||||||
|
NSTextAttachment *imageAttachment = [NSTextAttachment new];
|
||||||
|
imageAttachment.image = image;
|
||||||
|
[attributedString appendAttributedString:[NSAttributedString attributedStringWithAttachment:imageAttachment]];
|
||||||
} else {
|
} else {
|
||||||
RCTLogError(@"<Text> can't have any children except <Text> or raw strings");
|
//TODO: add placeholder image?
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
RCTLogError(@"<Text> can't have any children except <Text>, <Image> or raw strings");
|
||||||
}
|
}
|
||||||
|
|
||||||
[child setTextComputed];
|
[child setTextComputed];
|
||||||
|
|
|
@ -26,7 +26,6 @@ NSString *const RCTAccessibilityManagerDidUpdateMultiplierNotification = @"RCTAc
|
||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
@synthesize multipliers = _multipliers;
|
@synthesize multipliers = _multipliers;
|
||||||
@synthesize isVoiceOverEnabled = _isVoiceOverEnabled;
|
|
||||||
|
|
||||||
RCT_EXPORT_MODULE()
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
|
|
|
@ -189,6 +189,7 @@
|
||||||
13E067501A70F44B002CDEE1 /* RCTView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTView.m; sourceTree = "<group>"; };
|
13E067501A70F44B002CDEE1 /* RCTView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTView.m; sourceTree = "<group>"; };
|
||||||
13E067531A70F44B002CDEE1 /* UIView+React.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+React.h"; sourceTree = "<group>"; };
|
13E067531A70F44B002CDEE1 /* UIView+React.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+React.h"; sourceTree = "<group>"; };
|
||||||
13E067541A70F44B002CDEE1 /* UIView+React.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+React.m"; sourceTree = "<group>"; };
|
13E067541A70F44B002CDEE1 /* UIView+React.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+React.m"; sourceTree = "<group>"; };
|
||||||
|
13EF7F441BC69646003F47DD /* RCTImageComponent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTImageComponent.h; sourceTree = "<group>"; };
|
||||||
13F17A831B8493E5007D4C75 /* RCTRedBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRedBox.h; sourceTree = "<group>"; };
|
13F17A831B8493E5007D4C75 /* RCTRedBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRedBox.h; sourceTree = "<group>"; };
|
||||||
13F17A841B8493E5007D4C75 /* RCTRedBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRedBox.m; sourceTree = "<group>"; };
|
13F17A841B8493E5007D4C75 /* RCTRedBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRedBox.m; sourceTree = "<group>"; };
|
||||||
1403F2B11B0AE60700C2A9A4 /* RCTPerfStats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPerfStats.h; sourceTree = "<group>"; };
|
1403F2B11B0AE60700C2A9A4 /* RCTPerfStats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPerfStats.h; sourceTree = "<group>"; };
|
||||||
|
@ -341,6 +342,7 @@
|
||||||
13C325281AA63B6A0048765F /* RCTComponent.h */,
|
13C325281AA63B6A0048765F /* RCTComponent.h */,
|
||||||
13AB90BF1B6FA36700713B4F /* RCTComponentData.h */,
|
13AB90BF1B6FA36700713B4F /* RCTComponentData.h */,
|
||||||
13AB90C01B6FA36700713B4F /* RCTComponentData.m */,
|
13AB90C01B6FA36700713B4F /* RCTComponentData.m */,
|
||||||
|
13EF7F441BC69646003F47DD /* RCTImageComponent.h */,
|
||||||
13456E911ADAD2DE009F94A7 /* RCTConvert+CoreLocation.h */,
|
13456E911ADAD2DE009F94A7 /* RCTConvert+CoreLocation.h */,
|
||||||
13456E921ADAD2DE009F94A7 /* RCTConvert+CoreLocation.m */,
|
13456E921ADAD2DE009F94A7 /* RCTConvert+CoreLocation.m */,
|
||||||
13456E941ADAD482009F94A7 /* RCTConvert+MapKit.h */,
|
13456E941ADAD482009F94A7 /* RCTConvert+MapKit.h */,
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic interface for components that contain an image.
|
||||||
|
*/
|
||||||
|
@protocol RCTImageComponent <NSObject>
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) UIImage *image;
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in New Issue