Ported TabBarIOS to OSS and unified implementation

This commit is contained in:
Nick Lockwood
2015-03-05 16:36:41 -08:00
parent ab2537816f
commit fb2f063ef5
51 changed files with 1148 additions and 478 deletions

View File

@@ -0,0 +1,29 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule TabBarIOS
*/
'use strict';
var React = require('React');
var View = require('View');
var StyleSheet = require('StyleSheet');
var DummyTabBarIOS = React.createClass({
render: function() {
return (
<View style={[this.props.style, styles.tabGroup]}>
{this.props.children}
</View>
);
}
});
var styles = StyleSheet.create({
tabGroup: {
flex: 1,
}
});
module.exports = DummyTabBarIOS;

View File

@@ -0,0 +1,36 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule TabBarIOS
*/
'use strict';
var React = require('React');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var StyleSheet = require('StyleSheet');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var TabBarIOS = React.createClass({
render: function() {
return (
<RKTabBar style={[styles.tabGroup, this.props.style]}>
{this.props.children}
</RKTabBar>
);
}
});
var styles = StyleSheet.create({
tabGroup: {
flex: 1,
}
});
var config = {
validAttributes: ReactIOSViewAttributes.UIView,
uiViewClassName: 'RCTTabBar',
};
var RKTabBar = createReactIOSNativeComponentClass(config);
module.exports = TabBarIOS;

View File

@@ -0,0 +1,38 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule TabBarItemIOS
*/
'use strict';
var Dimensions = require('Dimensions');
var React = require('React');
var View = require('View');
var StyleSheet = require('StyleSheet');
var DummyTab = React.createClass({
render: function() {
if (!this.props.selected) {
return <View />;
}
return (
<View style={[this.props.style, styles.tab]}>
{this.props.children}
</View>
);
}
});
var styles = StyleSheet.create({
tab: {
// TODO(5405356): Implement overflow: visible so position: absolute isn't useless
// position: 'absolute',
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
borderColor: 'red',
borderWidth: 1,
}
});
module.exports = DummyTab;

View File

@@ -0,0 +1,94 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule TabBarItemIOS
*/
'use strict';
var Image = require('Image');
var React = require('React');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var Dimensions = require('Dimensions');
var StaticContainer = require('StaticContainer.react');
var StyleSheet = require('StyleSheet');
var View = require('View');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var merge = require('merge');
var TabBarItemIOS = React.createClass({
propTypes: {
icon: Image.sourcePropType.isRequired,
onPress: React.PropTypes.func.isRequired,
selected: React.PropTypes.bool.isRequired,
badgeValue: React.PropTypes.string,
title: React.PropTypes.string,
style: View.stylePropType,
},
getInitialState: function() {
return {
hasBeenSelected: false,
};
},
componentWillMount: function() {
if (this.props.selected) {
this.setState({hasBeenSelected: true});
}
},
componentWillReceiveProps: function(nextProps) {
if (this.state.hasBeenSelected || nextProps.selected) {
this.setState({hasBeenSelected: true});
}
},
render: function() {
var tabContents = null;
// if the tab has already been shown once, always continue to show it so we
// preserve state between tab transitions
if (this.state.hasBeenSelected) {
tabContents =
<StaticContainer shouldUpdate={this.props.selected}>
{this.props.children}
</StaticContainer>;
} else {
tabContents = <View />;
}
return (
<RKTabBarItem
icon={this.props.icon.uri}
selectedIcon={this.props.selectedIcon && this.props.selectedIcon.uri}
onPress={this.props.onPress}
selected={this.props.selected}
badgeValue={this.props.badgeValue}
title={this.props.title}
style={[styles.tab, this.props.style]}>
{tabContents}
</RKTabBarItem>
);
}
});
var styles = StyleSheet.create({
tab: {
position: 'absolute',
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
}
});
var RKTabBarItem = createReactIOSNativeComponentClass({
validAttributes: merge(ReactIOSViewAttributes.UIView, {
title: true,
icon: true,
selectedIcon: true,
selected: true,
badgeValue: true,
}),
uiViewClassName: 'RCTTabBarItem',
});
module.exports = TabBarItemIOS;

View File

@@ -0,0 +1,8 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <QuartzCore/QuartzCore.h>
extern CAKeyframeAnimation *RCTGIFImageWithData(NSData *data);
extern CAKeyframeAnimation *RCTGIFImageWithFileURL(NSURL *URL);

View File

@@ -0,0 +1,91 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import "RCTGIFImage.h"
#import "RCTLog.h"
static CAKeyframeAnimation *RCTGIFImageWithImageSource(CGImageSourceRef imageSource)
{
if (!UTTypeConformsTo(CGImageSourceGetType(imageSource), kUTTypeGIF)) {
CFRelease(imageSource);
return nil;
}
NSDictionary *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(imageSource, NULL);
NSUInteger loopCount = [properties[(id)kCGImagePropertyGIFDictionary][(id)kCGImagePropertyGIFLoopCount] unsignedIntegerValue];
size_t imageCount = CGImageSourceGetCount(imageSource);
NSTimeInterval duration = 0;
NSMutableArray *delays = [NSMutableArray arrayWithCapacity:imageCount];
NSMutableArray *images = [NSMutableArray arrayWithCapacity:imageCount];
for (size_t i = 0; i < imageCount; i++) {
CGImageRef image = CGImageSourceCreateImageAtIndex(imageSource, i, NULL);
NSDictionary *frameProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(imageSource, i, NULL);
NSDictionary *frameGIFProperties = frameProperties[(id)kCGImagePropertyGIFDictionary];
const NSTimeInterval kDelayTimeIntervalDefault = 0.1;
NSNumber *delayTime = frameGIFProperties[(id)kCGImagePropertyGIFUnclampedDelayTime] ?: frameGIFProperties[(id)kCGImagePropertyGIFDelayTime];
if (delayTime == nil) {
if (i == 0) {
delayTime = @(kDelayTimeIntervalDefault);
} else {
delayTime = delays[i - 1];
}
}
const NSTimeInterval kDelayTimeIntervalMinimum = 0.02;
if (delayTime.floatValue < (float)kDelayTimeIntervalMinimum - FLT_EPSILON) {
delayTime = @(kDelayTimeIntervalDefault);
}
duration += delayTime.doubleValue;
delays[i] = delayTime;
images[i] = (__bridge_transfer id)image;
}
NSMutableArray *keyTimes = [NSMutableArray arrayWithCapacity:delays.count];
NSTimeInterval runningDuration = 0;
for (NSNumber *delayNumber in delays) {
[keyTimes addObject:@(runningDuration / duration)];
runningDuration += delayNumber.doubleValue;
}
[keyTimes addObject:@1.0];
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
animation.calculationMode = kCAAnimationDiscrete;
animation.repeatCount = loopCount == 0 ? HUGE_VALF : loopCount;
animation.keyTimes = keyTimes;
animation.values = images;
animation.duration = duration;
return animation;
}
CAKeyframeAnimation *RCTGIFImageWithData(NSData *data)
{
if (data.length == 0) {
return nil;
}
CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)data, NULL);
CAKeyframeAnimation *animation = RCTGIFImageWithImageSource(imageSource);
CFRelease(imageSource);
return animation;
}
CAKeyframeAnimation *RCTGIFImageWithFileURL(NSURL *URL)
{
if (!URL) {
return nil;
}
if (![URL isFileURL]) {
RCTLogError(@"Loading remote image URLs synchronously is a really bad idea.");
return nil;
}
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)URL, NULL);
CAKeyframeAnimation *animation = RCTGIFImageWithImageSource(imageSource);
CFRelease(imageSource);
return animation;
}

View File

@@ -7,6 +7,9 @@
objects = {
/* Begin PBXBuildFile section */
1304D5AB1AA8C4A30002E2BE /* RCTStaticImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5A81AA8C4A30002E2BE /* RCTStaticImage.m */; };
1304D5AC1AA8C4A30002E2BE /* RCTStaticImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5AA1AA8C4A30002E2BE /* RCTStaticImageManager.m */; };
1304D5B21AA8C50D0002E2BE /* RCTGIFImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5B11AA8C50D0002E2BE /* RCTGIFImage.m */; };
58B5118F1A9E6BD600147676 /* RCTImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B5118A1A9E6BD600147676 /* RCTImageDownloader.m */; };
58B511901A9E6BD600147676 /* RCTNetworkImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B5118C1A9E6BD600147676 /* RCTNetworkImageView.m */; };
58B511911A9E6BD600147676 /* RCTNetworkImageViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B5118E1A9E6BD600147676 /* RCTNetworkImageViewManager.m */; };
@@ -25,7 +28,13 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
58B5115D1A9E6B3D00147676 /* libRCTNetworkImage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTNetworkImage.a; sourceTree = BUILT_PRODUCTS_DIR; };
1304D5A71AA8C4A30002E2BE /* RCTStaticImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTStaticImage.h; sourceTree = "<group>"; };
1304D5A81AA8C4A30002E2BE /* RCTStaticImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTStaticImage.m; sourceTree = "<group>"; };
1304D5A91AA8C4A30002E2BE /* RCTStaticImageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTStaticImageManager.h; sourceTree = "<group>"; };
1304D5AA1AA8C4A30002E2BE /* RCTStaticImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTStaticImageManager.m; sourceTree = "<group>"; };
1304D5B01AA8C50D0002E2BE /* RCTGIFImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTGIFImage.h; sourceTree = "<group>"; };
1304D5B11AA8C50D0002E2BE /* RCTGIFImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTGIFImage.m; sourceTree = "<group>"; };
58B5115D1A9E6B3D00147676 /* libRCTImage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTImage.a; sourceTree = BUILT_PRODUCTS_DIR; };
58B511891A9E6BD600147676 /* RCTImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageDownloader.h; sourceTree = "<group>"; };
58B5118A1A9E6BD600147676 /* RCTImageDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageDownloader.m; sourceTree = "<group>"; };
58B5118B1A9E6BD600147676 /* RCTNetworkImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTNetworkImageView.h; sourceTree = "<group>"; };
@@ -48,12 +57,18 @@
58B511541A9E6B3D00147676 = {
isa = PBXGroup;
children = (
1304D5B01AA8C50D0002E2BE /* RCTGIFImage.h */,
1304D5B11AA8C50D0002E2BE /* RCTGIFImage.m */,
58B511891A9E6BD600147676 /* RCTImageDownloader.h */,
58B5118A1A9E6BD600147676 /* RCTImageDownloader.m */,
58B5118B1A9E6BD600147676 /* RCTNetworkImageView.h */,
58B5118C1A9E6BD600147676 /* RCTNetworkImageView.m */,
58B5118D1A9E6BD600147676 /* RCTNetworkImageViewManager.h */,
58B5118E1A9E6BD600147676 /* RCTNetworkImageViewManager.m */,
1304D5A71AA8C4A30002E2BE /* RCTStaticImage.h */,
1304D5A81AA8C4A30002E2BE /* RCTStaticImage.m */,
1304D5A91AA8C4A30002E2BE /* RCTStaticImageManager.h */,
1304D5AA1AA8C4A30002E2BE /* RCTStaticImageManager.m */,
58B5115E1A9E6B3D00147676 /* Products */,
);
sourceTree = "<group>";
@@ -61,7 +76,7 @@
58B5115E1A9E6B3D00147676 /* Products */ = {
isa = PBXGroup;
children = (
58B5115D1A9E6B3D00147676 /* libRCTNetworkImage.a */,
58B5115D1A9E6B3D00147676 /* libRCTImage.a */,
);
name = Products;
sourceTree = "<group>";
@@ -69,9 +84,9 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
58B5115C1A9E6B3D00147676 /* RCTNetworkImage */ = {
58B5115C1A9E6B3D00147676 /* RCTImage */ = {
isa = PBXNativeTarget;
buildConfigurationList = 58B511711A9E6B3D00147676 /* Build configuration list for PBXNativeTarget "RCTNetworkImage" */;
buildConfigurationList = 58B511711A9E6B3D00147676 /* Build configuration list for PBXNativeTarget "RCTImage" */;
buildPhases = (
58B511591A9E6B3D00147676 /* Sources */,
58B5115A1A9E6B3D00147676 /* Frameworks */,
@@ -81,9 +96,9 @@
);
dependencies = (
);
name = RCTNetworkImage;
name = RCTImage;
productName = RCTNetworkImage;
productReference = 58B5115D1A9E6B3D00147676 /* libRCTNetworkImage.a */;
productReference = 58B5115D1A9E6B3D00147676 /* libRCTImage.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
@@ -100,7 +115,7 @@
};
};
};
buildConfigurationList = 58B511581A9E6B3D00147676 /* Build configuration list for PBXProject "RCTNetworkImage" */;
buildConfigurationList = 58B511581A9E6B3D00147676 /* Build configuration list for PBXProject "RCTImage" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
@@ -112,7 +127,7 @@
projectDirPath = "";
projectRoot = "";
targets = (
58B5115C1A9E6B3D00147676 /* RCTNetworkImage */,
58B5115C1A9E6B3D00147676 /* RCTImage */,
);
};
/* End PBXProject section */
@@ -124,7 +139,10 @@
files = (
58B5118F1A9E6BD600147676 /* RCTImageDownloader.m in Sources */,
58B511911A9E6BD600147676 /* RCTNetworkImageViewManager.m in Sources */,
1304D5AC1AA8C4A30002E2BE /* RCTStaticImageManager.m in Sources */,
58B511901A9E6BD600147676 /* RCTNetworkImageView.m in Sources */,
1304D5B21AA8C50D0002E2BE /* RCTGIFImage.m in Sources */,
1304D5AB1AA8C4A30002E2BE /* RCTStaticImage.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -213,8 +231,12 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../ReactKit/**",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/UIExplorer-gjaibsjtheitasdxdtcvxxqavkvy/Build/Products/Debug-iphoneos",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
PRODUCT_NAME = RCTImage;
SKIP_INSTALL = YES;
};
name = Debug;
@@ -227,8 +249,12 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../ReactKit/**",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/UIExplorer-gjaibsjtheitasdxdtcvxxqavkvy/Build/Products/Debug-iphoneos",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
PRODUCT_NAME = RCTImage;
SKIP_INSTALL = YES;
};
name = Release;
@@ -236,7 +262,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
58B511581A9E6B3D00147676 /* Build configuration list for PBXProject "RCTNetworkImage" */ = {
58B511581A9E6B3D00147676 /* Build configuration list for PBXProject "RCTImage" */ = {
isa = XCConfigurationList;
buildConfigurations = (
58B5116F1A9E6B3D00147676 /* Debug */,
@@ -245,7 +271,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
58B511711A9E6B3D00147676 /* Build configuration list for PBXNativeTarget "RCTNetworkImage" */ = {
58B511711A9E6B3D00147676 /* Build configuration list for PBXNativeTarget "RCTImage" */ = {
isa = XCConfigurationList;
buildConfigurations = (
58B511721A9E6B3D00147676 /* Debug */,

View File

@@ -109,39 +109,37 @@ typedef void (^RCTCachedDataDownloadBlock)(BOOL cached, NSData *data, NSError *e
- (id)downloadImageForURL:(NSURL *)url size:(CGSize)size scale:(CGFloat)scale block:(RCTImageDownloadBlock)block
{
NSString *cacheKey = [self cacheKeyForURL:url];
__weak RCTImageDownloader *weakSelf = self;
return [self _downloadDataForURL:url block:^(BOOL cached, NSData *data, NSError *error) {
if (!data) {
return dispatch_async(dispatch_get_main_queue(), ^{
block(nil, error);
});
}
return [self downloadDataForURL:url block:^(NSData *data, NSError *error) {
UIImage *image = [UIImage imageWithData:data scale:scale];
if (image) {
// Resize (TODO: should we take aspect ratio into account?)
CGSize imageSize = size;
if (CGSizeEqualToSize(imageSize, CGSizeZero)) {
imageSize = image.size;
} else {
imageSize = (CGSize){
MIN(size.width, image.size.width),
MIN(size.height, image.size.height)
};
}
// Rescale image if required size is smaller
CGFloat imageScale = scale;
if (imageScale == 0 || imageScale > image.scale) {
if (imageScale == 0 || imageScale < image.scale) {
imageScale = image.scale;
}
// Decompress image at required size
UIGraphicsBeginImageContextWithOptions(imageSize, NO, imageScale);
[image drawInRect:(CGRect){{0, 0}, imageSize}];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if (!cached) {
RCTImageDownloader *strongSelf = weakSelf;
[strongSelf->_cache setData:UIImagePNGRepresentation(image) forKey:cacheKey];
}
}
// TODO: should we cache the decompressed image?
dispatch_async(dispatch_get_main_queue(), ^{
block(image, nil);
});

View File

@@ -2,9 +2,10 @@
#import "RCTNetworkImageView.h"
#import "RCTConvert.h"
#import "RCTGIFImage.h"
#import "RCTImageDownloader.h"
#import "RCTUtils.h"
#import "RCTConvert.h"
@implementation RCTNetworkImageView
{
@@ -53,7 +54,7 @@
if ([imageURL.pathExtension caseInsensitiveCompare:@"gif"] == NSOrderedSame) {
_downloadToken = [_imageDownloader downloadDataForURL:imageURL block:^(NSData *data, NSError *error) {
if (data) {
CAKeyframeAnimation *animation = [RCTConvert GIF:data];
CAKeyframeAnimation *animation = RCTGIFImageWithData(data);
CGImageRef firstFrame = (__bridge CGImageRef)animation.values.firstObject;
self.layer.bounds = CGRectMake(0, 0, CGImageGetWidth(firstFrame), CGImageGetHeight(firstFrame));
self.layer.contentsScale = 1.0;

View File

@@ -23,4 +23,3 @@ RCT_REMAP_VIEW_PROPERTY(src, imageURL)
RCT_REMAP_VIEW_PROPERTY(resizeMode, contentMode)
@end

View File

@@ -0,0 +1,10 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import <UIKit/UIKit.h>
@interface RCTStaticImage : UIImageView
@property (nonatomic, assign) UIEdgeInsets capInsets;
@property (nonatomic, assign) UIImageRenderingMode renderingMode;
@end

View File

@@ -0,0 +1,55 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import "RCTStaticImage.h"
@implementation RCTStaticImage
- (void)_updateImage
{
UIImage *image = self.image;
if (!image) {
return;
}
// Apply rendering mode
if (_renderingMode != image.renderingMode) {
image = [image imageWithRenderingMode:_renderingMode];
}
// Applying capInsets of 0 will switch the "resizingMode" of the image to "tile" which is undesired
if (!UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, _capInsets)) {
image = [image resizableImageWithCapInsets:_capInsets resizingMode:UIImageResizingModeStretch];
}
// Apply trilinear filtering to smooth out mis-sized images
self.layer.minificationFilter = kCAFilterTrilinear;
self.layer.magnificationFilter = kCAFilterTrilinear;
super.image = image;
}
- (void)setImage:(UIImage *)image
{
if (image != super.image) {
super.image = image;
[self _updateImage];
}
}
- (void)setCapInsets:(UIEdgeInsets)capInsets
{
if (!UIEdgeInsetsEqualToEdgeInsets(_capInsets, capInsets)) {
_capInsets = capInsets;
[self _updateImage];
}
}
- (void)setRenderingMode:(UIImageRenderingMode)renderingMode
{
if (_renderingMode != renderingMode) {
_renderingMode = renderingMode;
[self _updateImage];
}
}
@end

View File

@@ -0,0 +1,7 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import "RCTViewManager.h"
@interface RCTStaticImageManager : RCTViewManager
@end

View File

@@ -0,0 +1,43 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import "RCTStaticImageManager.h"
#import <UIKit/UIKit.h>
#import "RCTConvert.h"
#import "RCTGIFImage.h"
#import "RCTStaticImage.h"
@implementation RCTStaticImageManager
- (UIView *)view
{
return [[RCTStaticImage alloc] init];
}
RCT_EXPORT_VIEW_PROPERTY(capInsets)
RCT_REMAP_VIEW_PROPERTY(resizeMode, contentMode)
RCT_CUSTOM_VIEW_PROPERTY(src, RCTStaticImage *)
{
if (json) {
if ([[[json description] pathExtension] caseInsensitiveCompare:@"gif"] == NSOrderedSame) {
[view.layer addAnimation:RCTGIFImageWithFileURL([RCTConvert NSURL:json]) forKey:@"contents"];
} else {
view.image = [RCTConvert UIImage:json];
}
} else {
view.image = defaultView.image;
}
}
RCT_CUSTOM_VIEW_PROPERTY(tintColor, RCTStaticImage *)
{
if (json) {
view.renderingMode = UIImageRenderingModeAlwaysTemplate;
view.tintColor = [RCTConvert UIColor:json];
} else {
view.renderingMode = defaultView.renderingMode;
view.tintColor = defaultView.tintColor;
}
}
@end

View File

@@ -23,7 +23,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
58B511DB1A9E6C8500147676 /* libRCTDataManager.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTDataManager.a; sourceTree = BUILT_PRODUCTS_DIR; };
58B511DB1A9E6C8500147676 /* libRCTNetwork.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTNetwork.a; sourceTree = BUILT_PRODUCTS_DIR; };
58B512061A9E6CE300147676 /* RCTDataManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDataManager.h; sourceTree = "<group>"; };
58B512071A9E6CE300147676 /* RCTDataManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDataManager.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -51,7 +51,7 @@
58B511DC1A9E6C8500147676 /* Products */ = {
isa = PBXGroup;
children = (
58B511DB1A9E6C8500147676 /* libRCTDataManager.a */,
58B511DB1A9E6C8500147676 /* libRCTNetwork.a */,
);
name = Products;
sourceTree = "<group>";
@@ -59,9 +59,9 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
58B511DA1A9E6C8500147676 /* RCTDataManager */ = {
58B511DA1A9E6C8500147676 /* RCTNetwork */ = {
isa = PBXNativeTarget;
buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTDataManager" */;
buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTNetwork" */;
buildPhases = (
58B511D71A9E6C8500147676 /* Sources */,
58B511D81A9E6C8500147676 /* Frameworks */,
@@ -71,9 +71,9 @@
);
dependencies = (
);
name = RCTDataManager;
name = RCTNetwork;
productName = RCTDataManager;
productReference = 58B511DB1A9E6C8500147676 /* libRCTDataManager.a */;
productReference = 58B511DB1A9E6C8500147676 /* libRCTNetwork.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
@@ -90,7 +90,7 @@
};
};
};
buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTDataManager" */;
buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTNetwork" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
@@ -102,7 +102,7 @@
projectDirPath = "";
projectRoot = "";
targets = (
58B511DA1A9E6C8500147676 /* RCTDataManager */,
58B511DA1A9E6C8500147676 /* RCTNetwork */,
);
};
/* End PBXProject section */
@@ -206,7 +206,7 @@
"/Users/nicklockwood/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/ReactKit/build/Debug-iphoneos",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
PRODUCT_NAME = RCTNetwork;
SKIP_INSTALL = YES;
};
name = Debug;
@@ -224,7 +224,7 @@
"/Users/nicklockwood/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/ReactKit/build/Debug-iphoneos",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
PRODUCT_NAME = RCTNetwork;
SKIP_INSTALL = YES;
};
name = Release;
@@ -232,7 +232,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTDataManager" */ = {
58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTNetwork" */ = {
isa = XCConfigurationList;
buildConfigurations = (
58B511ED1A9E6C8500147676 /* Debug */,
@@ -241,7 +241,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTDataManager" */ = {
58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTNetwork" */ = {
isa = XCConfigurationList;
buildConfigurations = (
58B511F01A9E6C8500147676 /* Debug */,