Updates from Thu Mar 5

- [react_native] JS files for D1885531 | Martin Konicek
- Ported TabBarIOS to OSS and unified implementation | Nick Lockwood
- [react-packager] Add minify option as query param | Amjad Masad
- [ReactNative] Fix ExpandingText prop types | Christopher Chedeau
- [react-packager] Make dev a query param option | Amjad Masad
This commit is contained in:
Christopher Chedeau 2015-03-06 09:54:10 -08:00
parent 990979f8a6
commit 61b8c61903
62 changed files with 1290 additions and 579 deletions

View File

@ -7,23 +7,30 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1341801E1AA91750003F314A /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341801B1AA91740003F314A /* libRCTNetwork.a */; };
13442C061AA90EA00037E5B0 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13442C051AA90E7D0037E5B0 /* libRCTImage.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
58C572691AA6239800CDF9C8 /* libRCTDataManager.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C572631AA6236600CDF9C8 /* libRCTDataManager.a */; };
58C5726A1AA6239B00CDF9C8 /* libRCTNetworkImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C572561AA6236500CDF9C8 /* libRCTNetworkImage.a */; };
58C5726B1AA6239E00CDF9C8 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C5725B1AA6236500CDF9C8 /* libRCTText.a */; }; 58C5726B1AA6239E00CDF9C8 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C5725B1AA6236500CDF9C8 /* libRCTText.a */; };
58C5726C1AA623A200CDF9C8 /* libReactKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C572681AA6236600CDF9C8 /* libReactKit.a */; }; 58C5726C1AA623A200CDF9C8 /* libReactKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C572681AA6236600CDF9C8 /* libReactKit.a */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
58C572551AA6236500CDF9C8 /* PBXContainerItemProxy */ = { 1341801A1AA91740003F314A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = 587650F31A9EB120008B8F17 /* RCTNetworkImage.xcodeproj */; containerPortal = 134180151AA91740003F314A /* RCTNetwork.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 58B511DB1A9E6C8500147676;
remoteInfo = RCTNetwork;
};
13442C041AA90E7D0037E5B0 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 13442C001AA90E7D0037E5B0 /* RCTImage.xcodeproj */;
proxyType = 2; proxyType = 2;
remoteGlobalIDString = 58B5115D1A9E6B3D00147676; remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
remoteInfo = RCTNetworkImage; remoteInfo = RCTImage;
}; };
58C5725A1AA6236500CDF9C8 /* PBXContainerItemProxy */ = { 58C5725A1AA6236500CDF9C8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
@ -32,13 +39,6 @@
remoteGlobalIDString = 58B5119B1A9E6C1200147676; remoteGlobalIDString = 58B5119B1A9E6C1200147676;
remoteInfo = RCTText; remoteInfo = RCTText;
}; };
58C572621AA6236600CDF9C8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 587650F01A9EB120008B8F17 /* RCTDataManager.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 58B511DB1A9E6C8500147676;
remoteInfo = RCTDataManager;
};
58C572671AA6236600CDF9C8 /* PBXContainerItemProxy */ = { 58C572671AA6236600CDF9C8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = 587650F91A9EB120008B8F17 /* ReactKit.xcodeproj */; containerPortal = 587650F91A9EB120008B8F17 /* ReactKit.xcodeproj */;
@ -49,6 +49,8 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
134180151AA91740003F314A /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
13442C001AA90E7D0037E5B0 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* Movies.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Movies.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07F961A680F5B00A75B9A /* Movies.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Movies.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@ -56,8 +58,6 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
587650F01A9EB120008B8F17 /* RCTDataManager.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTDataManager.xcodeproj; path = ../../Libraries/Network/RCTDataManager.xcodeproj; sourceTree = SOURCE_ROOT; };
587650F31A9EB120008B8F17 /* RCTNetworkImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetworkImage.xcodeproj; path = ../../Libraries/Image/RCTNetworkImage.xcodeproj; sourceTree = SOURCE_ROOT; };
587650F61A9EB120008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = SOURCE_ROOT; }; 587650F61A9EB120008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = SOURCE_ROOT; };
587650F91A9EB120008B8F17 /* ReactKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactKit.xcodeproj; path = ../../ReactKit/ReactKit.xcodeproj; sourceTree = SOURCE_ROOT; }; 587650F91A9EB120008B8F17 /* ReactKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactKit.xcodeproj; path = ../../ReactKit/ReactKit.xcodeproj; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -67,8 +67,8 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
58C572691AA6239800CDF9C8 /* libRCTDataManager.a in Frameworks */, 1341801E1AA91750003F314A /* libRCTNetwork.a in Frameworks */,
58C5726A1AA6239B00CDF9C8 /* libRCTNetworkImage.a in Frameworks */, 13442C061AA90EA00037E5B0 /* libRCTImage.a in Frameworks */,
58C5726B1AA6239E00CDF9C8 /* libRCTText.a in Frameworks */, 58C5726B1AA6239E00CDF9C8 /* libRCTText.a in Frameworks */,
58C5726C1AA623A200CDF9C8 /* libReactKit.a in Frameworks */, 58C5726C1AA623A200CDF9C8 /* libReactKit.a in Frameworks */,
); );
@ -77,6 +77,22 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
134180161AA91740003F314A /* Products */ = {
isa = PBXGroup;
children = (
1341801B1AA91740003F314A /* libRCTNetwork.a */,
);
name = Products;
sourceTree = "<group>";
};
13442C011AA90E7D0037E5B0 /* Products */ = {
isa = PBXGroup;
children = (
13442C051AA90E7D0037E5B0 /* libRCTImage.a */,
);
name = Products;
sourceTree = "<group>";
};
13B07FAE1A68108700A75B9A /* Movies */ = { 13B07FAE1A68108700A75B9A /* Movies */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -93,22 +109,14 @@
58C571FC1AA6124500CDF9C8 /* Libraries */ = { 58C571FC1AA6124500CDF9C8 /* Libraries */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
587650F01A9EB120008B8F17 /* RCTDataManager.xcodeproj */, 134180151AA91740003F314A /* RCTNetwork.xcodeproj */,
587650F31A9EB120008B8F17 /* RCTNetworkImage.xcodeproj */, 13442C001AA90E7D0037E5B0 /* RCTImage.xcodeproj */,
587650F61A9EB120008B8F17 /* RCTText.xcodeproj */, 587650F61A9EB120008B8F17 /* RCTText.xcodeproj */,
587650F91A9EB120008B8F17 /* ReactKit.xcodeproj */, 587650F91A9EB120008B8F17 /* ReactKit.xcodeproj */,
); );
name = Libraries; name = Libraries;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
58C572521AA6236500CDF9C8 /* Products */ = {
isa = PBXGroup;
children = (
58C572561AA6236500CDF9C8 /* libRCTNetworkImage.a */,
);
name = Products;
sourceTree = "<group>";
};
58C572571AA6236500CDF9C8 /* Products */ = { 58C572571AA6236500CDF9C8 /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -125,14 +133,6 @@
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
58C5725E1AA6236500CDF9C8 /* Products */ = {
isa = PBXGroup;
children = (
58C572631AA6236600CDF9C8 /* libRCTDataManager.a */,
);
name = Products;
sourceTree = "<group>";
};
83CBB9F61A601CBA00E9B192 = { 83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -192,12 +192,12 @@
projectDirPath = ""; projectDirPath = "";
projectReferences = ( projectReferences = (
{ {
ProductGroup = 58C5725E1AA6236500CDF9C8 /* Products */; ProductGroup = 13442C011AA90E7D0037E5B0 /* Products */;
ProjectRef = 587650F01A9EB120008B8F17 /* RCTDataManager.xcodeproj */; ProjectRef = 13442C001AA90E7D0037E5B0 /* RCTImage.xcodeproj */;
}, },
{ {
ProductGroup = 58C572521AA6236500CDF9C8 /* Products */; ProductGroup = 134180161AA91740003F314A /* Products */;
ProjectRef = 587650F31A9EB120008B8F17 /* RCTNetworkImage.xcodeproj */; ProjectRef = 134180151AA91740003F314A /* RCTNetwork.xcodeproj */;
}, },
{ {
ProductGroup = 58C572571AA6236500CDF9C8 /* Products */; ProductGroup = 58C572571AA6236500CDF9C8 /* Products */;
@ -216,11 +216,18 @@
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXReferenceProxy section */ /* Begin PBXReferenceProxy section */
58C572561AA6236500CDF9C8 /* libRCTNetworkImage.a */ = { 1341801B1AA91740003F314A /* libRCTNetwork.a */ = {
isa = PBXReferenceProxy; isa = PBXReferenceProxy;
fileType = archive.ar; fileType = archive.ar;
path = libRCTNetworkImage.a; path = libRCTNetwork.a;
remoteRef = 58C572551AA6236500CDF9C8 /* PBXContainerItemProxy */; remoteRef = 1341801A1AA91740003F314A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
13442C051AA90E7D0037E5B0 /* libRCTImage.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTImage.a;
remoteRef = 13442C041AA90E7D0037E5B0 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR; sourceTree = BUILT_PRODUCTS_DIR;
}; };
58C5725B1AA6236500CDF9C8 /* libRCTText.a */ = { 58C5725B1AA6236500CDF9C8 /* libRCTText.a */ = {
@ -230,13 +237,6 @@
remoteRef = 58C5725A1AA6236500CDF9C8 /* PBXContainerItemProxy */; remoteRef = 58C5725A1AA6236500CDF9C8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR; sourceTree = BUILT_PRODUCTS_DIR;
}; };
58C572631AA6236600CDF9C8 /* libRCTDataManager.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTDataManager.a;
remoteRef = 58C572621AA6236600CDF9C8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
58C572681AA6236600CDF9C8 /* libReactKit.a */ = { 58C572681AA6236600CDF9C8 /* libReactKit.a */ = {
isa = PBXReferenceProxy; isa = PBXReferenceProxy;
fileType = archive.ar; fileType = archive.ar;
@ -295,6 +295,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"/Users/nicklockwood/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/Libraries/Network/build/Debug-iphoneos",
); );
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = Movies; PRODUCT_NAME = Movies;
@ -314,6 +315,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"/Users/nicklockwood/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/Libraries/Network/build/Debug-iphoneos",
); );
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = Movies; PRODUCT_NAME = Movies;

View File

@ -7,29 +7,22 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1341803E1AA91802003F314A /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341803D1AA917ED003F314A /* libRCTImage.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
58C571F31AA611C900CDF9C8 /* libRCTNetworkImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C571ED1AA611BA00CDF9C8 /* libRCTNetworkImage.a */; };
58C572501AA6229900CDF9C8 /* libReactKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C572471AA6224300CDF9C8 /* libReactKit.a */; }; 58C572501AA6229900CDF9C8 /* libReactKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C572471AA6224300CDF9C8 /* libReactKit.a */; };
58C572511AA6229D00CDF9C8 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C5724D1AA6224400CDF9C8 /* libRCTText.a */; }; 58C572511AA6229D00CDF9C8 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C5724D1AA6224400CDF9C8 /* libRCTText.a */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
58C571EC1AA611BA00CDF9C8 /* PBXContainerItemProxy */ = { 1341803C1AA917ED003F314A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = 58C571E71AA611BA00CDF9C8 /* RCTNetworkImage.xcodeproj */; containerPortal = 134180381AA917ED003F314A /* RCTImage.xcodeproj */;
proxyType = 2; proxyType = 2;
remoteGlobalIDString = 58B5115D1A9E6B3D00147676; remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
remoteInfo = RCTNetworkImage; remoteInfo = RCTImage;
};
58C571EE1AA611BA00CDF9C8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 58C571E71AA611BA00CDF9C8 /* RCTNetworkImage.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 58B511681A9E6B3D00147676;
remoteInfo = RCTNetworkImageTests;
}; };
58C572461AA6224300CDF9C8 /* PBXContainerItemProxy */ = { 58C572461AA6224300CDF9C8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
@ -45,16 +38,10 @@
remoteGlobalIDString = 58B5119B1A9E6C1200147676; remoteGlobalIDString = 58B5119B1A9E6C1200147676;
remoteInfo = RCTText; remoteInfo = RCTText;
}; };
58C5724E1AA6224400CDF9C8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 58B511A61A9E6C1300147676;
remoteInfo = RCTTextTests;
};
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
134180381AA917ED003F314A /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* TicTacToe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TicTacToe.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07F961A680F5B00A75B9A /* TicTacToe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TicTacToe.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@ -64,7 +51,6 @@
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; }; 587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
587650E31A9EB0DF008B8F17 /* ReactKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactKit.xcodeproj; path = ../../ReactKit/ReactKit.xcodeproj; sourceTree = "<group>"; }; 587650E31A9EB0DF008B8F17 /* ReactKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactKit.xcodeproj; path = ../../ReactKit/ReactKit.xcodeproj; sourceTree = "<group>"; };
58C571E71AA611BA00CDF9C8 /* RCTNetworkImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetworkImage.xcodeproj; path = ../../Libraries/Image/RCTNetworkImage.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -72,7 +58,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
58C571F31AA611C900CDF9C8 /* libRCTNetworkImage.a in Frameworks */, 1341803E1AA91802003F314A /* libRCTImage.a in Frameworks */,
58C572501AA6229900CDF9C8 /* libReactKit.a in Frameworks */, 58C572501AA6229900CDF9C8 /* libReactKit.a in Frameworks */,
58C572511AA6229D00CDF9C8 /* libRCTText.a in Frameworks */, 58C572511AA6229D00CDF9C8 /* libRCTText.a in Frameworks */,
); );
@ -81,6 +67,14 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
134180391AA917ED003F314A /* Products */ = {
isa = PBXGroup;
children = (
1341803D1AA917ED003F314A /* libRCTImage.a */,
);
name = Products;
sourceTree = "<group>";
};
13B07FAE1A68108700A75B9A /* TicTacToe */ = { 13B07FAE1A68108700A75B9A /* TicTacToe */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -94,19 +88,10 @@
name = TicTacToe; name = TicTacToe;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
58C571E81AA611BA00CDF9C8 /* Products */ = {
isa = PBXGroup;
children = (
58C571ED1AA611BA00CDF9C8 /* libRCTNetworkImage.a */,
58C571EF1AA611BA00CDF9C8 /* RCTNetworkImageTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
58C572071AA6126D00CDF9C8 /* Libraries */ = { 58C572071AA6126D00CDF9C8 /* Libraries */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
58C571E71AA611BA00CDF9C8 /* RCTNetworkImage.xcodeproj */, 134180381AA917ED003F314A /* RCTImage.xcodeproj */,
587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */, 587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */,
587650E31A9EB0DF008B8F17 /* ReactKit.xcodeproj */, 587650E31A9EB0DF008B8F17 /* ReactKit.xcodeproj */,
); );
@ -125,7 +110,6 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
58C5724D1AA6224400CDF9C8 /* libRCTText.a */, 58C5724D1AA6224400CDF9C8 /* libRCTText.a */,
58C5724F1AA6224400CDF9C8 /* RCTTextTests.xctest */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@ -189,8 +173,8 @@
projectDirPath = ""; projectDirPath = "";
projectReferences = ( projectReferences = (
{ {
ProductGroup = 58C571E81AA611BA00CDF9C8 /* Products */; ProductGroup = 134180391AA917ED003F314A /* Products */;
ProjectRef = 58C571E71AA611BA00CDF9C8 /* RCTNetworkImage.xcodeproj */; ProjectRef = 134180381AA917ED003F314A /* RCTImage.xcodeproj */;
}, },
{ {
ProductGroup = 58C572481AA6224300CDF9C8 /* Products */; ProductGroup = 58C572481AA6224300CDF9C8 /* Products */;
@ -209,18 +193,11 @@
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXReferenceProxy section */ /* Begin PBXReferenceProxy section */
58C571ED1AA611BA00CDF9C8 /* libRCTNetworkImage.a */ = { 1341803D1AA917ED003F314A /* libRCTImage.a */ = {
isa = PBXReferenceProxy; isa = PBXReferenceProxy;
fileType = archive.ar; fileType = archive.ar;
path = libRCTNetworkImage.a; path = libRCTImage.a;
remoteRef = 58C571EC1AA611BA00CDF9C8 /* PBXContainerItemProxy */; remoteRef = 1341803C1AA917ED003F314A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
58C571EF1AA611BA00CDF9C8 /* RCTNetworkImageTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RCTNetworkImageTests.xctest;
remoteRef = 58C571EE1AA611BA00CDF9C8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR; sourceTree = BUILT_PRODUCTS_DIR;
}; };
58C572471AA6224300CDF9C8 /* libReactKit.a */ = { 58C572471AA6224300CDF9C8 /* libReactKit.a */ = {
@ -237,13 +214,6 @@
remoteRef = 58C5724C1AA6224400CDF9C8 /* PBXContainerItemProxy */; remoteRef = 58C5724C1AA6224400CDF9C8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR; sourceTree = BUILT_PRODUCTS_DIR;
}; };
58C5724F1AA6224400CDF9C8 /* RCTTextTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RCTTextTests.xctest;
remoteRef = 58C5724E1AA6224400CDF9C8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */ /* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
@ -288,9 +258,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = "$(inherited)";
"$(inherited)",
);
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = TicTacToe; PRODUCT_NAME = TicTacToe;
}; };
@ -302,9 +270,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = "$(inherited)";
"$(inherited)",
);
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = TicTacToe; PRODUCT_NAME = TicTacToe;
}; };

View File

@ -0,0 +1,101 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule TabBarExample
*/
'use strict';
var React = require('React');
var TabBarIOS = require('TabBarIOS');
var TabBarItemIOS = require('TabBarItemIOS');
var StyleSheet = require('StyleSheet');
var Text = require('Text');
var View = require('View');
var ix = require('ix');
var TabBarExample = React.createClass({
statics: {
title: '<TabBarIOS>',
description: 'Tab-based navigation.'
},
getInitialState: function() {
return {
selectedTab: 'redTab',
notifCount: 0,
presses: 0,
};
},
_renderContent: function(color, pageText) {
return (
<View style={[styles.tabContent, {backgroundColor: color}]}>
<Text style={styles.tabText}>{pageText}</Text>
<Text style={styles.tabText}>{this.state.presses} re-renders of this tab</Text>
</View>
);
},
render: function() {
return (
<TabBarIOS
selectedTab={this.state.selectedTab}>
<TabBarItemIOS
name="blueTab"
icon={ix('favorites')}
accessibilityLabel="Blue Tab"
selected={this.state.selectedTab === 'blueTab'}
onPress={() => {
this.setState({
selectedTab: 'blueTab',
});
}}>
{this._renderContent('#414A8C', 'Blue Tab')}
</TabBarItemIOS>
<TabBarItemIOS
accessibilityLabel="Red Tab"
name="redTab"
icon={ix('history')}
badgeValue={this.state.notifCount ? String(this.state.notifCount) : null}
selected={this.state.selectedTab === 'redTab'}
onPress={() => {
this.setState({
selectedTab: 'redTab',
notifCount: this.state.notifCount + 1,
});
}}>
{this._renderContent('#783E33', 'Red Tab')}
</TabBarItemIOS>
<TabBarItemIOS
name="greenTab"
icon={ix('more')}
accessibilityLabel="Green Tab"
selected={this.state.selectedTab === 'greenTab'}
onPress={() => {
this.setState({
selectedTab: 'greenTab',
presses: this.state.presses + 1
});
}}>
{this._renderContent('#21551C', 'Green Tab')}
</TabBarItemIOS>
</TabBarIOS>
);
},
});
var styles = StyleSheet.create({
tabContent: {
flex: 1,
alignItems: 'center',
},
tabText: {
color: 'white',
margin: 50,
},
});
module.exports = TabBarExample;

View File

@ -7,48 +7,52 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1316A21A1AA397CA00C0188E /* libRCTNetworkImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1316A2101AA3871A00C0188E /* libRCTNetworkImage.a */; }; 13417FE91AA91432003F314A /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FE81AA91428003F314A /* libRCTImage.a */; };
1316A21B1AA397CA00C0188E /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1316A2081AA386C700C0188E /* libRCTText.a */; }; 134180011AA9153C003F314A /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FEF1AA914B8003F314A /* libRCTText.a */; };
1316A21C1AA397CA00C0188E /* libReactKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1316A2171AA3875D00C0188E /* libReactKit.a */; }; 134180021AA9153C003F314A /* libReactKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FFF1AA91531003F314A /* libReactKit.a */; };
1341802C1AA9178B003F314A /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341802B1AA91779003F314A /* libRCTNetwork.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
58C572891AA624A900CDF9C8 /* libRCTDataManager.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C572851AA6249E00CDF9C8 /* libRCTDataManager.a */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
1316A2071AA386C700C0188E /* PBXContainerItemProxy */ = { 13417FE71AA91428003F314A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = 5876511F1A9EB168008B8F17 /* RCTText.xcodeproj */; containerPortal = 13417FE31AA91428003F314A /* RCTImage.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
remoteInfo = RCTImage;
};
13417FEE1AA914B8003F314A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 13417FEA1AA914B8003F314A /* RCTText.xcodeproj */;
proxyType = 2; proxyType = 2;
remoteGlobalIDString = 58B5119B1A9E6C1200147676; remoteGlobalIDString = 58B5119B1A9E6C1200147676;
remoteInfo = RCTText; remoteInfo = RCTText;
}; };
1316A20F1AA3871A00C0188E /* PBXContainerItemProxy */ = { 13417FFE1AA91531003F314A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = 5876511C1A9EB168008B8F17 /* RCTNetworkImage.xcodeproj */; containerPortal = 13417FFA1AA91531003F314A /* ReactKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
remoteInfo = RCTNetworkImage;
};
1316A2161AA3875D00C0188E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 587651221A9EB168008B8F17 /* ReactKit.xcodeproj */;
proxyType = 2; proxyType = 2;
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
remoteInfo = ReactKit; remoteInfo = ReactKit;
}; };
58C572841AA6249E00CDF9C8 /* PBXContainerItemProxy */ = { 1341802A1AA91779003F314A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = 587651491A9F8619008B8F17 /* RCTDataManager.xcodeproj */; containerPortal = 134180261AA91779003F314A /* RCTNetwork.xcodeproj */;
proxyType = 2; proxyType = 2;
remoteGlobalIDString = 58B511DB1A9E6C8500147676; remoteGlobalIDString = 58B511DB1A9E6C8500147676;
remoteInfo = RCTDataManager; remoteInfo = RCTNetwork;
}; };
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
13417FE31AA91428003F314A /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
13417FFA1AA91531003F314A /* ReactKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactKit.xcodeproj; path = ../../ReactKit/ReactKit.xcodeproj; sourceTree = "<group>"; };
134180261AA91779003F314A /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* UIExplorer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UIExplorer.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07F961A680F5B00A75B9A /* UIExplorer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UIExplorer.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@ -56,10 +60,6 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
5876511C1A9EB168008B8F17 /* RCTNetworkImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetworkImage.xcodeproj; path = ../../Libraries/Image/RCTNetworkImage.xcodeproj; sourceTree = SOURCE_ROOT; };
5876511F1A9EB168008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = SOURCE_ROOT; };
587651221A9EB168008B8F17 /* ReactKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactKit.xcodeproj; path = ../../ReactKit/ReactKit.xcodeproj; sourceTree = SOURCE_ROOT; };
587651491A9F8619008B8F17 /* RCTDataManager.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTDataManager.xcodeproj; path = ../../Libraries/Network/RCTDataManager.xcodeproj; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -67,51 +67,59 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
1316A21A1AA397CA00C0188E /* libRCTNetworkImage.a in Frameworks */, 1341802C1AA9178B003F314A /* libRCTNetwork.a in Frameworks */,
1316A21B1AA397CA00C0188E /* libRCTText.a in Frameworks */, 134180011AA9153C003F314A /* libRCTText.a in Frameworks */,
58C572891AA624A900CDF9C8 /* libRCTDataManager.a in Frameworks */, 134180021AA9153C003F314A /* libReactKit.a in Frameworks */,
1316A21C1AA397CA00C0188E /* libReactKit.a in Frameworks */, 13417FE91AA91432003F314A /* libRCTImage.a in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
1316A2031AA386C700C0188E /* Products */ = {
isa = PBXGroup;
children = (
1316A2081AA386C700C0188E /* libRCTText.a */,
);
name = Products;
sourceTree = "<group>";
};
1316A20B1AA3871A00C0188E /* Products */ = {
isa = PBXGroup;
children = (
1316A2101AA3871A00C0188E /* libRCTNetworkImage.a */,
);
name = Products;
sourceTree = "<group>";
};
1316A2131AA3875D00C0188E /* Products */ = {
isa = PBXGroup;
children = (
1316A2171AA3875D00C0188E /* libReactKit.a */,
);
name = Products;
sourceTree = "<group>";
};
1316A21D1AA397F400C0188E /* Libraries */ = { 1316A21D1AA397F400C0188E /* Libraries */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
587651221A9EB168008B8F17 /* ReactKit.xcodeproj */, 13417FFA1AA91531003F314A /* ReactKit.xcodeproj */,
587651491A9F8619008B8F17 /* RCTDataManager.xcodeproj */, 134180261AA91779003F314A /* RCTNetwork.xcodeproj */,
5876511C1A9EB168008B8F17 /* RCTNetworkImage.xcodeproj */, 13417FEA1AA914B8003F314A /* RCTText.xcodeproj */,
5876511F1A9EB168008B8F17 /* RCTText.xcodeproj */, 13417FE31AA91428003F314A /* RCTImage.xcodeproj */,
); );
name = Libraries; name = Libraries;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
13417FE41AA91428003F314A /* Products */ = {
isa = PBXGroup;
children = (
13417FE81AA91428003F314A /* libRCTImage.a */,
);
name = Products;
sourceTree = "<group>";
};
13417FEB1AA914B8003F314A /* Products */ = {
isa = PBXGroup;
children = (
13417FEF1AA914B8003F314A /* libRCTText.a */,
);
name = Products;
sourceTree = "<group>";
};
13417FFB1AA91531003F314A /* Products */ = {
isa = PBXGroup;
children = (
13417FFF1AA91531003F314A /* libReactKit.a */,
);
name = Products;
sourceTree = "<group>";
};
134180271AA91779003F314A /* Products */ = {
isa = PBXGroup;
children = (
1341802B1AA91779003F314A /* libRCTNetwork.a */,
);
name = Products;
sourceTree = "<group>";
};
13B07FAE1A68108700A75B9A /* UIExplorer */ = { 13B07FAE1A68108700A75B9A /* UIExplorer */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -125,14 +133,6 @@
name = UIExplorer; name = UIExplorer;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
58C572811AA6249E00CDF9C8 /* Products */ = {
isa = PBXGroup;
children = (
58C572851AA6249E00CDF9C8 /* libRCTDataManager.a */,
);
name = Products;
sourceTree = "<group>";
};
83CBB9F61A601CBA00E9B192 = { 83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -192,20 +192,20 @@
projectDirPath = ""; projectDirPath = "";
projectReferences = ( projectReferences = (
{ {
ProductGroup = 58C572811AA6249E00CDF9C8 /* Products */; ProductGroup = 13417FE41AA91428003F314A /* Products */;
ProjectRef = 587651491A9F8619008B8F17 /* RCTDataManager.xcodeproj */; ProjectRef = 13417FE31AA91428003F314A /* RCTImage.xcodeproj */;
}, },
{ {
ProductGroup = 1316A20B1AA3871A00C0188E /* Products */; ProductGroup = 134180271AA91779003F314A /* Products */;
ProjectRef = 5876511C1A9EB168008B8F17 /* RCTNetworkImage.xcodeproj */; ProjectRef = 134180261AA91779003F314A /* RCTNetwork.xcodeproj */;
}, },
{ {
ProductGroup = 1316A2031AA386C700C0188E /* Products */; ProductGroup = 13417FEB1AA914B8003F314A /* Products */;
ProjectRef = 5876511F1A9EB168008B8F17 /* RCTText.xcodeproj */; ProjectRef = 13417FEA1AA914B8003F314A /* RCTText.xcodeproj */;
}, },
{ {
ProductGroup = 1316A2131AA3875D00C0188E /* Products */; ProductGroup = 13417FFB1AA91531003F314A /* Products */;
ProjectRef = 587651221A9EB168008B8F17 /* ReactKit.xcodeproj */; ProjectRef = 13417FFA1AA91531003F314A /* ReactKit.xcodeproj */;
}, },
); );
projectRoot = ""; projectRoot = "";
@ -216,32 +216,32 @@
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXReferenceProxy section */ /* Begin PBXReferenceProxy section */
1316A2081AA386C700C0188E /* libRCTText.a */ = { 13417FE81AA91428003F314A /* libRCTImage.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTImage.a;
remoteRef = 13417FE71AA91428003F314A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
13417FEF1AA914B8003F314A /* libRCTText.a */ = {
isa = PBXReferenceProxy; isa = PBXReferenceProxy;
fileType = archive.ar; fileType = archive.ar;
path = libRCTText.a; path = libRCTText.a;
remoteRef = 1316A2071AA386C700C0188E /* PBXContainerItemProxy */; remoteRef = 13417FEE1AA914B8003F314A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR; sourceTree = BUILT_PRODUCTS_DIR;
}; };
1316A2101AA3871A00C0188E /* libRCTNetworkImage.a */ = { 13417FFF1AA91531003F314A /* libReactKit.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTNetworkImage.a;
remoteRef = 1316A20F1AA3871A00C0188E /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
1316A2171AA3875D00C0188E /* libReactKit.a */ = {
isa = PBXReferenceProxy; isa = PBXReferenceProxy;
fileType = archive.ar; fileType = archive.ar;
path = libReactKit.a; path = libReactKit.a;
remoteRef = 1316A2161AA3875D00C0188E /* PBXContainerItemProxy */; remoteRef = 13417FFE1AA91531003F314A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR; sourceTree = BUILT_PRODUCTS_DIR;
}; };
58C572851AA6249E00CDF9C8 /* libRCTDataManager.a */ = { 1341802B1AA91779003F314A /* libRCTNetwork.a */ = {
isa = PBXReferenceProxy; isa = PBXReferenceProxy;
fileType = archive.ar; fileType = archive.ar;
path = libRCTDataManager.a; path = libRCTNetwork.a;
remoteRef = 58C572841AA6249E00CDF9C8 /* PBXContainerItemProxy */; remoteRef = 1341802A1AA91779003F314A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR; sourceTree = BUILT_PRODUCTS_DIR;
}; };
/* End PBXReferenceProxy section */ /* End PBXReferenceProxy section */
@ -293,9 +293,7 @@
); );
INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = "$(inherited)";
"$(inherited)",
);
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = UIExplorer; PRODUCT_NAME = UIExplorer;
}; };
@ -312,9 +310,7 @@
); );
INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = "$(inherited)";
"$(inherited)",
);
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = UIExplorer; PRODUCT_NAME = UIExplorer;
}; };

View File

@ -32,6 +32,7 @@ var EXAMPLES = [
require('./ActivityIndicatorExample'), require('./ActivityIndicatorExample'),
require('./ScrollViewExample'), require('./ScrollViewExample'),
require('./GeoLocationExample'), require('./GeoLocationExample'),
require('./TabBarExample'),
]; ];
var UIExplorerList = React.createClass({ var UIExplorerList = React.createClass({

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

@ -71,7 +71,7 @@ var View = React.createClass({
accessible: PropTypes.bool, accessible: PropTypes.bool,
/** /**
* This string can be used to identify the accessible element. * Used to locate this view in end-to-end tests.
*/ */
testID: PropTypes.string, testID: PropTypes.string,

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

View File

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

View File

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

View File

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

View File

@ -4,8 +4,9 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "RCTStaticImage.h"
#import "RCTConvert.h" #import "RCTConvert.h"
#import "RCTGIFImage.h"
#import "RCTStaticImage.h"
@implementation RCTStaticImageManager @implementation RCTStaticImageManager
@ -20,7 +21,7 @@ RCT_CUSTOM_VIEW_PROPERTY(src, RCTStaticImage *)
{ {
if (json) { if (json) {
if ([[[json description] pathExtension] caseInsensitiveCompare:@"gif"] == NSOrderedSame) { if ([[[json description] pathExtension] caseInsensitiveCompare:@"gif"] == NSOrderedSame) {
[view.layer addAnimation:[RCTConvert GIF:json] forKey:@"contents"]; [view.layer addAnimation:RCTGIFImageWithFileURL([RCTConvert NSURL:json]) forKey:@"contents"];
} else { } else {
view.image = [RCTConvert UIImage:json]; view.image = [RCTConvert UIImage:json];
} }
@ -40,4 +41,3 @@ RCT_CUSTOM_VIEW_PROPERTY(tintColor, RCTStaticImage *)
} }
@end @end

View File

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

View File

@ -20,39 +20,49 @@ var styles = StyleSheet.create({
}); });
/** /**
* <ExpandingText> - A react component for displaying text which supports truncating * A react component for displaying text which supports truncating
* based on a set truncLength. In the following example, the text will truncate * based on a set truncLength.
* to show only the first 17 characters plus '...' with a See More button to
* expand the text to its full length
* *
* renderText: function() { * In the following example, the text will truncate
* to show only the first 17 characters plus '...' with a See More button to
* expand the text to its full length.
*
* ```
* render: function() {
* return <ExpandingText truncLength={20} text={EXAMPLE_TEXT} />; * return <ExpandingText truncLength={20} text={EXAMPLE_TEXT} />;
* }, * },
* * ```
* More example code in `ExpandingTextExample.js`
*/ */
var ExpandingText = React.createClass({ var ExpandingText = React.createClass({
PropTypes: { propTypes: {
/** /**
* Text to be displayed. Text will be truncated if the character length * Text to be displayed. It will be truncated if the character length
* is greater than the truncLength property. * is greater than the `truncLength` property.
*/ */
text: React.PropTypes.string.isRequired, text: React.PropTypes.string,
/** /**
* The styles that will be applied to the text (both truncated and expanded). * The styles that will be applied to the text (both truncated and
* expanded).
*/ */
textStyle: Text.stylePropType, textStyle: Text.propTypes.style,
/** /**
* The styles that will be applied to the See More button * The styles that will be applied to the See More button. Default
* is bold.
*/ */
seeMoreStyle: Text.stylePropType, seeMoreStyle: Text.propTypes.style,
/**
* The caption that will be appended at the end, by default it is
* `'See More'`.
*/
seeMoreText: React.PropTypes.string,
/** /**
* The maximum character length for the text that will * The maximum character length for the text that will
* be displayed by default. Note that ... will be * be displayed by default. Note that ... will be
* appended to the truncated text which is counted towards * appended to the truncated text which is counted towards
* the total truncLength of the default displayed string * the total truncLength of the default displayed string.
* The default is 130.
*/ */
truncLength: React.PropTypes.number truncLength: React.PropTypes.number,
}, },
getDefaultProps: function() { getDefaultProps: function() {

View File

@ -87,6 +87,10 @@ var Text = React.createClass({
*/ */
suppressHighlighting: React.PropTypes.bool, suppressHighlighting: React.PropTypes.bool,
style: stylePropType, style: stylePropType,
/**
* Used to locate this view in end-to-end tests.
*/
testID: React.PropTypes.string,
}, },
viewConfig: viewConfig, viewConfig: viewConfig,

View File

@ -3,9 +3,9 @@
#import <QuartzCore/QuartzCore.h> #import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "Layout.h" #import "../Layout/Layout.h"
#import "RCTPointerEvents.h" #import "../Views/RCTAnimationType.h"
#import "RCTAnimationType.h" #import "../Views/RCTPointerEvents.h"
/** /**
* This class provides a collection of conversion functions for mapping * This class provides a collection of conversion functions for mapping
@ -47,7 +47,6 @@
+ (UIColor *)UIColor:(id)json; + (UIColor *)UIColor:(id)json;
+ (CGColorRef)CGColor:(id)json; + (CGColorRef)CGColor:(id)json;
+ (CAKeyframeAnimation *)GIF:(id)json;
+ (UIImage *)UIImage:(id)json; + (UIImage *)UIImage:(id)json;
+ (CGImageRef)CGImage:(id)json; + (CGImageRef)CGImage:(id)json;
@ -68,6 +67,10 @@
@end @end
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* This function will attempt to set a property using a json value by first * This function will attempt to set a property using a json value by first
* inferring the correct type from all available information, and then * inferring the correct type from all available information, and then
@ -82,3 +85,7 @@ BOOL RCTSetProperty(id target, NSString *keypath, id json);
* be set, it will do nothing and return NO. * be set, it will do nothing and return NO.
*/ */
BOOL RCTCopyProperty(id target, id source, NSString *keypath); BOOL RCTCopyProperty(id target, id source, NSString *keypath);
#ifdef __cplusplus
}
#endif

View File

@ -4,9 +4,6 @@
#import <objc/message.h> #import <objc/message.h>
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "RCTLog.h" #import "RCTLog.h"
CGFloat const RCTDefaultFontSize = 14; CGFloat const RCTDefaultFontSize = 14;
@ -431,88 +428,11 @@ RCT_STRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty"]
return [self UIColor:json].CGColor; return [self UIColor:json].CGColor;
} }
+ (CAKeyframeAnimation *)GIF:(id)json
{
CGImageSourceRef imageSource = NULL;
if ([json isKindOfClass:[NSString class]]) {
NSString *path = json;
if (path.length == 0) {
return nil;
}
NSURL *fileURL = [path isAbsolutePath] ? [NSURL fileURLWithPath:path] : [[NSBundle mainBundle] URLForResource:path withExtension:nil];
imageSource = CGImageSourceCreateWithURL((CFURLRef)fileURL, NULL);
} else if ([json isKindOfClass:[NSData class]]) {
NSData *data = json;
if (data.length == 0) {
return nil;
}
imageSource = CGImageSourceCreateWithData((CFDataRef)data, NULL);
} else {
RCTLogMustFix(@"Expected NSString or NSData for GIF, received %@: %@", [json class], json);
return nil;
}
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;
}
CFRelease(imageSource);
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;
}
+ (UIImage *)UIImage:(id)json + (UIImage *)UIImage:(id)json
{ {
// TODO: we might as well cache the result of these checks (and possibly the
// image itself) so as to reduce overhead on subsequent checks of the same input
if (![json isKindOfClass:[NSString class]]) { if (![json isKindOfClass:[NSString class]]) {
RCTLogError(@"Expected NSString for UIImage, received %@: %@", [json class], json); RCTLogError(@"Expected NSString for UIImage, received %@: %@", [json class], json);
return nil; return nil;
@ -532,9 +452,8 @@ RCT_STRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty"]
image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:path ofType:nil]]; image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:path ofType:nil]];
} }
} }
if (!image) { // NOTE: we don't warn about nil images because there are legitimate
RCTLogWarn(@"No image was found at path %@", json); // case where we find out if a string is an image by using this method
}
return image; return image;
} }

View File

@ -1109,8 +1109,8 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
// Bubble dispatched events // Bubble dispatched events
@"topTap": @{ @"topTap": @{
@"phasedRegistrationNames": @{ @"phasedRegistrationNames": @{
@"bubbled": @"notActuallyTapDontUseMe", @"bubbled": @"onPress",
@"captured": @"notActuallyTapCaptureDontUseMe" @"captured": @"onPressCapture"
} }
}, },
@"topVisibleCellsChange": @{ @"topVisibleCellsChange": @{

View File

@ -7,12 +7,14 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1302F0FD1A78550100EBEF02 /* RCTStaticImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1302F0FA1A78550100EBEF02 /* RCTStaticImage.m */; };
1302F0FE1A78550100EBEF02 /* RCTStaticImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1302F0FC1A78550100EBEF02 /* RCTStaticImageManager.m */; };
134FCB361A6D42D900051CC8 /* RCTSparseArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 83BEE46D1A6D19BC00B5863B /* RCTSparseArray.m */; }; 134FCB361A6D42D900051CC8 /* RCTSparseArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 83BEE46D1A6D19BC00B5863B /* RCTSparseArray.m */; };
134FCB3D1A6E7F0800051CC8 /* RCTContextExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 134FCB3A1A6E7F0800051CC8 /* RCTContextExecutor.m */; }; 134FCB3D1A6E7F0800051CC8 /* RCTContextExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 134FCB3A1A6E7F0800051CC8 /* RCTContextExecutor.m */; };
134FCB3E1A6E7F0800051CC8 /* RCTWebViewExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 134FCB3C1A6E7F0800051CC8 /* RCTWebViewExecutor.m */; }; 134FCB3E1A6E7F0800051CC8 /* RCTWebViewExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 134FCB3C1A6E7F0800051CC8 /* RCTWebViewExecutor.m */; };
13723B501A82FD3C00F88898 /* RCTStatusBarManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13723B4F1A82FD3C00F88898 /* RCTStatusBarManager.m */; }; 13723B501A82FD3C00F88898 /* RCTStatusBarManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13723B4F1A82FD3C00F88898 /* RCTStatusBarManager.m */; };
137327E71AA5CF210034F82E /* RCTTabBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 137327E01AA5CF210034F82E /* RCTTabBar.m */; };
137327E81AA5CF210034F82E /* RCTTabBarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 137327E21AA5CF210034F82E /* RCTTabBarItem.m */; };
137327E91AA5CF210034F82E /* RCTTabBarItemManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 137327E41AA5CF210034F82E /* RCTTabBarItemManager.m */; };
137327EA1AA5CF210034F82E /* RCTTabBarManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 137327E61AA5CF210034F82E /* RCTTabBarManager.m */; };
13A1F71E1A75392D00D3D453 /* RCTKeyCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = 13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */; }; 13A1F71E1A75392D00D3D453 /* RCTKeyCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = 13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */; };
13B07FEF1A69327A00A75B9A /* RCTAlertManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FE81A69327A00A75B9A /* RCTAlertManager.m */; }; 13B07FEF1A69327A00A75B9A /* RCTAlertManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FE81A69327A00A75B9A /* RCTAlertManager.m */; };
13B07FF01A69327A00A75B9A /* RCTExceptionsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FEA1A69327A00A75B9A /* RCTExceptionsManager.m */; }; 13B07FF01A69327A00A75B9A /* RCTExceptionsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FEA1A69327A00A75B9A /* RCTExceptionsManager.m */; };
@ -60,21 +62,27 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1302F0F91A78550100EBEF02 /* RCTStaticImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTStaticImage.h; sourceTree = "<group>"; }; 13442BF21AA90E0B0037E5B0 /* RCTAnimationType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAnimationType.h; sourceTree = "<group>"; };
1302F0FA1A78550100EBEF02 /* RCTStaticImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTStaticImage.m; sourceTree = "<group>"; }; 13442BF31AA90E0B0037E5B0 /* RCTPointerEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPointerEvents.h; sourceTree = "<group>"; };
1302F0FB1A78550100EBEF02 /* RCTStaticImageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTStaticImageManager.h; sourceTree = "<group>"; }; 13442BF41AA90E0B0037E5B0 /* RCTViewControllerProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTViewControllerProtocol.h; sourceTree = "<group>"; };
1302F0FC1A78550100EBEF02 /* RCTStaticImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTStaticImageManager.m; sourceTree = "<group>"; };
134FCB391A6E7F0800051CC8 /* RCTContextExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTContextExecutor.h; sourceTree = "<group>"; }; 134FCB391A6E7F0800051CC8 /* RCTContextExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTContextExecutor.h; sourceTree = "<group>"; };
134FCB3A1A6E7F0800051CC8 /* RCTContextExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTContextExecutor.m; sourceTree = "<group>"; }; 134FCB3A1A6E7F0800051CC8 /* RCTContextExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTContextExecutor.m; sourceTree = "<group>"; };
134FCB3B1A6E7F0800051CC8 /* RCTWebViewExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebViewExecutor.h; sourceTree = "<group>"; }; 134FCB3B1A6E7F0800051CC8 /* RCTWebViewExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebViewExecutor.h; sourceTree = "<group>"; };
134FCB3C1A6E7F0800051CC8 /* RCTWebViewExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebViewExecutor.m; sourceTree = "<group>"; }; 134FCB3C1A6E7F0800051CC8 /* RCTWebViewExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebViewExecutor.m; sourceTree = "<group>"; };
13723B4E1A82FD3C00F88898 /* RCTStatusBarManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTStatusBarManager.h; sourceTree = "<group>"; }; 13723B4E1A82FD3C00F88898 /* RCTStatusBarManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTStatusBarManager.h; sourceTree = "<group>"; };
13723B4F1A82FD3C00F88898 /* RCTStatusBarManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTStatusBarManager.m; sourceTree = "<group>"; }; 13723B4F1A82FD3C00F88898 /* RCTStatusBarManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTStatusBarManager.m; sourceTree = "<group>"; };
137327DF1AA5CF210034F82E /* RCTTabBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTabBar.h; sourceTree = "<group>"; };
137327E01AA5CF210034F82E /* RCTTabBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTabBar.m; sourceTree = "<group>"; };
137327E11AA5CF210034F82E /* RCTTabBarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTabBarItem.h; sourceTree = "<group>"; };
137327E21AA5CF210034F82E /* RCTTabBarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTabBarItem.m; sourceTree = "<group>"; };
137327E31AA5CF210034F82E /* RCTTabBarItemManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTabBarItemManager.h; sourceTree = "<group>"; };
137327E41AA5CF210034F82E /* RCTTabBarItemManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTabBarItemManager.m; sourceTree = "<group>"; };
137327E51AA5CF210034F82E /* RCTTabBarManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTabBarManager.h; sourceTree = "<group>"; };
137327E61AA5CF210034F82E /* RCTTabBarManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTabBarManager.m; sourceTree = "<group>"; };
13A1F71C1A75392D00D3D453 /* RCTKeyCommands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTKeyCommands.h; sourceTree = "<group>"; }; 13A1F71C1A75392D00D3D453 /* RCTKeyCommands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTKeyCommands.h; sourceTree = "<group>"; };
13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTKeyCommands.m; sourceTree = "<group>"; }; 13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTKeyCommands.m; sourceTree = "<group>"; };
13B07FC71A68125100A75B9A /* Layout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Layout.c; sourceTree = "<group>"; }; 13B07FC71A68125100A75B9A /* Layout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Layout.c; sourceTree = "<group>"; };
13B07FC81A68125100A75B9A /* Layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Layout.h; sourceTree = "<group>"; }; 13B07FC81A68125100A75B9A /* Layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Layout.h; sourceTree = "<group>"; };
13B07FCD1A683B5F00A75B9A /* RCTScrollableProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTScrollableProtocol.h; sourceTree = "<group>"; };
13B07FE71A69327A00A75B9A /* RCTAlertManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAlertManager.h; sourceTree = "<group>"; }; 13B07FE71A69327A00A75B9A /* RCTAlertManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAlertManager.h; sourceTree = "<group>"; };
13B07FE81A69327A00A75B9A /* RCTAlertManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAlertManager.m; sourceTree = "<group>"; }; 13B07FE81A69327A00A75B9A /* RCTAlertManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAlertManager.m; sourceTree = "<group>"; };
13B07FE91A69327A00A75B9A /* RCTExceptionsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTExceptionsManager.h; sourceTree = "<group>"; }; 13B07FE91A69327A00A75B9A /* RCTExceptionsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTExceptionsManager.h; sourceTree = "<group>"; };
@ -101,7 +109,9 @@
13B080191A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIActivityIndicatorViewManager.m; sourceTree = "<group>"; }; 13B080191A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIActivityIndicatorViewManager.m; sourceTree = "<group>"; };
13B080231A694A8400A75B9A /* RCTWrapperViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWrapperViewController.h; sourceTree = "<group>"; }; 13B080231A694A8400A75B9A /* RCTWrapperViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWrapperViewController.h; sourceTree = "<group>"; };
13B080241A694A8400A75B9A /* RCTWrapperViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWrapperViewController.m; sourceTree = "<group>"; }; 13B080241A694A8400A75B9A /* RCTWrapperViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWrapperViewController.m; sourceTree = "<group>"; };
13DB9D681A8CC58200429C20 /* RCTAnimationType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAnimationType.h; sourceTree = "<group>"; }; 13C325261AA63B6A0048765F /* RCTAutoInsetsProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAutoInsetsProtocol.h; sourceTree = "<group>"; };
13C325271AA63B6A0048765F /* RCTScrollableProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTScrollableProtocol.h; sourceTree = "<group>"; };
13C325281AA63B6A0048765F /* RCTViewNodeProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTViewNodeProtocol.h; sourceTree = "<group>"; };
13E067481A70F434002CDEE1 /* RCTUIManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTUIManager.h; sourceTree = "<group>"; }; 13E067481A70F434002CDEE1 /* RCTUIManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTUIManager.h; sourceTree = "<group>"; };
13E067491A70F434002CDEE1 /* RCTUIManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIManager.m; sourceTree = "<group>"; }; 13E067491A70F434002CDEE1 /* RCTUIManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIManager.m; sourceTree = "<group>"; };
13E0674B1A70F44B002CDEE1 /* RCTShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTShadowView.h; sourceTree = "<group>"; }; 13E0674B1A70F44B002CDEE1 /* RCTShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTShadowView.h; sourceTree = "<group>"; };
@ -112,7 +122,6 @@
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+ReactKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+ReactKit.h"; sourceTree = "<group>"; }; 13E067531A70F44B002CDEE1 /* UIView+ReactKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+ReactKit.h"; sourceTree = "<group>"; };
13E067541A70F44B002CDEE1 /* UIView+ReactKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+ReactKit.m"; sourceTree = "<group>"; }; 13E067541A70F44B002CDEE1 /* UIView+ReactKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+ReactKit.m"; sourceTree = "<group>"; };
13ED13891A80C9D40050A8F9 /* RCTPointerEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPointerEvents.h; sourceTree = "<group>"; };
13EFFCCF1A98E6FE002607DC /* RCTJSMethodRegistrar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJSMethodRegistrar.h; sourceTree = "<group>"; }; 13EFFCCF1A98E6FE002607DC /* RCTJSMethodRegistrar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJSMethodRegistrar.h; sourceTree = "<group>"; };
5F5F0D971A9E456B001279FA /* RCTLocationObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTLocationObserver.h; sourceTree = "<group>"; }; 5F5F0D971A9E456B001279FA /* RCTLocationObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTLocationObserver.h; sourceTree = "<group>"; };
5F5F0D981A9E456B001279FA /* RCTLocationObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTLocationObserver.m; sourceTree = "<group>"; }; 5F5F0D981A9E456B001279FA /* RCTLocationObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTLocationObserver.m; sourceTree = "<group>"; };
@ -135,8 +144,6 @@
83CBBA591A601E9000E9B192 /* RCTRedBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRedBox.m; sourceTree = "<group>"; }; 83CBBA591A601E9000E9B192 /* RCTRedBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRedBox.m; sourceTree = "<group>"; };
83CBBA5E1A601EAA00E9B192 /* RCTBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBridge.h; sourceTree = "<group>"; }; 83CBBA5E1A601EAA00E9B192 /* RCTBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBridge.h; sourceTree = "<group>"; };
83CBBA5F1A601EAA00E9B192 /* RCTBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBridge.m; sourceTree = "<group>"; }; 83CBBA5F1A601EAA00E9B192 /* RCTBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBridge.m; sourceTree = "<group>"; };
83CBBA611A601EB200E9B192 /* RCTAutoInsetsProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTAutoInsetsProtocol.h; sourceTree = "<group>"; };
83CBBA621A601EB800E9B192 /* RCTViewNodeProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTViewNodeProtocol.h; sourceTree = "<group>"; };
83CBBA631A601ECA00E9B192 /* RCTJavaScriptExecutor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTJavaScriptExecutor.h; sourceTree = "<group>"; }; 83CBBA631A601ECA00E9B192 /* RCTJavaScriptExecutor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTJavaScriptExecutor.h; sourceTree = "<group>"; };
83CBBA651A601EF300E9B192 /* RCTEventDispatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTEventDispatcher.h; sourceTree = "<group>"; }; 83CBBA651A601EF300E9B192 /* RCTEventDispatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTEventDispatcher.h; sourceTree = "<group>"; };
83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTEventDispatcher.m; sourceTree = "<group>"; }; 83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTEventDispatcher.m; sourceTree = "<group>"; };
@ -199,6 +206,12 @@
13B07FF31A6947C200A75B9A /* Views */ = { 13B07FF31A6947C200A75B9A /* Views */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
13442BF21AA90E0B0037E5B0 /* RCTAnimationType.h */,
13442BF31AA90E0B0037E5B0 /* RCTPointerEvents.h */,
13442BF41AA90E0B0037E5B0 /* RCTViewControllerProtocol.h */,
13C325261AA63B6A0048765F /* RCTAutoInsetsProtocol.h */,
13C325271AA63B6A0048765F /* RCTScrollableProtocol.h */,
13C325281AA63B6A0048765F /* RCTViewNodeProtocol.h */,
13B0800C1A69489C00A75B9A /* RCTNavigator.h */, 13B0800C1A69489C00A75B9A /* RCTNavigator.h */,
13B0800D1A69489C00A75B9A /* RCTNavigator.m */, 13B0800D1A69489C00A75B9A /* RCTNavigator.m */,
13B0800E1A69489C00A75B9A /* RCTNavigatorManager.h */, 13B0800E1A69489C00A75B9A /* RCTNavigatorManager.h */,
@ -213,10 +226,6 @@
13B07FF91A6947C200A75B9A /* RCTScrollViewManager.m */, 13B07FF91A6947C200A75B9A /* RCTScrollViewManager.m */,
13E0674B1A70F44B002CDEE1 /* RCTShadowView.h */, 13E0674B1A70F44B002CDEE1 /* RCTShadowView.h */,
13E0674C1A70F44B002CDEE1 /* RCTShadowView.m */, 13E0674C1A70F44B002CDEE1 /* RCTShadowView.m */,
1302F0F91A78550100EBEF02 /* RCTStaticImage.h */,
1302F0FA1A78550100EBEF02 /* RCTStaticImage.m */,
1302F0FB1A78550100EBEF02 /* RCTStaticImageManager.h */,
1302F0FC1A78550100EBEF02 /* RCTStaticImageManager.m */,
13B080141A69489C00A75B9A /* RCTTextField.h */, 13B080141A69489C00A75B9A /* RCTTextField.h */,
13B080151A69489C00A75B9A /* RCTTextField.m */, 13B080151A69489C00A75B9A /* RCTTextField.m */,
13B080161A69489C00A75B9A /* RCTTextFieldManager.h */, 13B080161A69489C00A75B9A /* RCTTextFieldManager.h */,
@ -229,6 +238,14 @@
13E0674E1A70F44B002CDEE1 /* RCTViewManager.m */, 13E0674E1A70F44B002CDEE1 /* RCTViewManager.m */,
13B080231A694A8400A75B9A /* RCTWrapperViewController.h */, 13B080231A694A8400A75B9A /* RCTWrapperViewController.h */,
13B080241A694A8400A75B9A /* RCTWrapperViewController.m */, 13B080241A694A8400A75B9A /* RCTWrapperViewController.m */,
137327DF1AA5CF210034F82E /* RCTTabBar.h */,
137327E01AA5CF210034F82E /* RCTTabBar.m */,
137327E11AA5CF210034F82E /* RCTTabBarItem.h */,
137327E21AA5CF210034F82E /* RCTTabBarItem.m */,
137327E31AA5CF210034F82E /* RCTTabBarItemManager.h */,
137327E41AA5CF210034F82E /* RCTTabBarItemManager.m */,
137327E51AA5CF210034F82E /* RCTTabBarManager.h */,
137327E61AA5CF210034F82E /* RCTTabBarManager.m */,
13E067531A70F44B002CDEE1 /* UIView+ReactKit.h */, 13E067531A70F44B002CDEE1 /* UIView+ReactKit.h */,
13E067541A70F44B002CDEE1 /* UIView+ReactKit.m */, 13E067541A70F44B002CDEE1 /* UIView+ReactKit.m */,
); );
@ -266,10 +283,8 @@
83CBBA491A601E3B00E9B192 /* Base */ = { 83CBBA491A601E3B00E9B192 /* Base */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
13DB9D681A8CC58200429C20 /* RCTAnimationType.h */,
83CBBA4A1A601E3B00E9B192 /* RCTAssert.h */, 83CBBA4A1A601E3B00E9B192 /* RCTAssert.h */,
83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */, 83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */,
83CBBA611A601EB200E9B192 /* RCTAutoInsetsProtocol.h */,
83CBBA5E1A601EAA00E9B192 /* RCTBridge.h */, 83CBBA5E1A601EAA00E9B192 /* RCTBridge.h */,
83CBBA5F1A601EAA00E9B192 /* RCTBridge.m */, 83CBBA5F1A601EAA00E9B192 /* RCTBridge.m */,
830213F31A654E0800B993E6 /* RCTBridgeModule.h */, 830213F31A654E0800B993E6 /* RCTBridgeModule.h */,
@ -286,19 +301,16 @@
13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */, 13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */,
83CBBA4D1A601E3B00E9B192 /* RCTLog.h */, 83CBBA4D1A601E3B00E9B192 /* RCTLog.h */,
83CBBA4E1A601E3B00E9B192 /* RCTLog.m */, 83CBBA4E1A601E3B00E9B192 /* RCTLog.m */,
13ED13891A80C9D40050A8F9 /* RCTPointerEvents.h */,
83CBBA581A601E9000E9B192 /* RCTRedBox.h */, 83CBBA581A601E9000E9B192 /* RCTRedBox.h */,
83CBBA591A601E9000E9B192 /* RCTRedBox.m */, 83CBBA591A601E9000E9B192 /* RCTRedBox.m */,
830A229C1A66C68A008503DA /* RCTRootView.h */, 830A229C1A66C68A008503DA /* RCTRootView.h */,
830A229D1A66C68A008503DA /* RCTRootView.m */, 830A229D1A66C68A008503DA /* RCTRootView.m */,
13B07FCD1A683B5F00A75B9A /* RCTScrollableProtocol.h */,
83BEE46C1A6D19BC00B5863B /* RCTSparseArray.h */, 83BEE46C1A6D19BC00B5863B /* RCTSparseArray.h */,
83BEE46D1A6D19BC00B5863B /* RCTSparseArray.m */, 83BEE46D1A6D19BC00B5863B /* RCTSparseArray.m */,
83CBBA961A6020BB00E9B192 /* RCTTouchHandler.h */, 83CBBA961A6020BB00E9B192 /* RCTTouchHandler.h */,
83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */, 83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */,
83CBBA4F1A601E3B00E9B192 /* RCTUtils.h */, 83CBBA4F1A601E3B00E9B192 /* RCTUtils.h */,
83CBBA501A601E3B00E9B192 /* RCTUtils.m */, 83CBBA501A601E3B00E9B192 /* RCTUtils.m */,
83CBBA621A601EB800E9B192 /* RCTViewNodeProtocol.h */,
); );
path = Base; path = Base;
sourceTree = "<group>"; sourceTree = "<group>";
@ -383,7 +395,6 @@
83CBBACC1A6023D300E9B192 /* RCTConvert.m in Sources */, 83CBBACC1A6023D300E9B192 /* RCTConvert.m in Sources */,
5F5F0D991A9E456B001279FA /* RCTLocationObserver.m in Sources */, 5F5F0D991A9E456B001279FA /* RCTLocationObserver.m in Sources */,
830A229E1A66C68A008503DA /* RCTRootView.m in Sources */, 830A229E1A66C68A008503DA /* RCTRootView.m in Sources */,
1302F0FD1A78550100EBEF02 /* RCTStaticImage.m in Sources */,
13B07FF01A69327A00A75B9A /* RCTExceptionsManager.m in Sources */, 13B07FF01A69327A00A75B9A /* RCTExceptionsManager.m in Sources */,
83CBBA5A1A601E9000E9B192 /* RCTRedBox.m in Sources */, 83CBBA5A1A601E9000E9B192 /* RCTRedBox.m in Sources */,
83CBBA511A601E3B00E9B192 /* RCTAssert.m in Sources */, 83CBBA511A601E3B00E9B192 /* RCTAssert.m in Sources */,
@ -391,6 +402,7 @@
13B080201A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.m in Sources */, 13B080201A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.m in Sources */,
13E067561A70F44B002CDEE1 /* RCTViewManager.m in Sources */, 13E067561A70F44B002CDEE1 /* RCTViewManager.m in Sources */,
13B080061A6947C200A75B9A /* RCTScrollViewManager.m in Sources */, 13B080061A6947C200A75B9A /* RCTScrollViewManager.m in Sources */,
137327EA1AA5CF210034F82E /* RCTTabBarManager.m in Sources */,
13B080261A694A8400A75B9A /* RCTWrapperViewController.m in Sources */, 13B080261A694A8400A75B9A /* RCTWrapperViewController.m in Sources */,
13B080051A6947C200A75B9A /* RCTScrollView.m in Sources */, 13B080051A6947C200A75B9A /* RCTScrollView.m in Sources */,
13B07FF21A69327A00A75B9A /* RCTTiming.m in Sources */, 13B07FF21A69327A00A75B9A /* RCTTiming.m in Sources */,
@ -401,18 +413,20 @@
83CBBA521A601E3B00E9B192 /* RCTLog.m in Sources */, 83CBBA521A601E3B00E9B192 /* RCTLog.m in Sources */,
13B0801D1A69489C00A75B9A /* RCTNavItemManager.m in Sources */, 13B0801D1A69489C00A75B9A /* RCTNavItemManager.m in Sources */,
13E067571A70F44B002CDEE1 /* RCTView.m in Sources */, 13E067571A70F44B002CDEE1 /* RCTView.m in Sources */,
137327E91AA5CF210034F82E /* RCTTabBarItemManager.m in Sources */,
134FCB361A6D42D900051CC8 /* RCTSparseArray.m in Sources */, 134FCB361A6D42D900051CC8 /* RCTSparseArray.m in Sources */,
13A1F71E1A75392D00D3D453 /* RCTKeyCommands.m in Sources */, 13A1F71E1A75392D00D3D453 /* RCTKeyCommands.m in Sources */,
83CBBA531A601E3B00E9B192 /* RCTUtils.m in Sources */, 83CBBA531A601E3B00E9B192 /* RCTUtils.m in Sources */,
83CBBA601A601EAA00E9B192 /* RCTBridge.m in Sources */, 83CBBA601A601EAA00E9B192 /* RCTBridge.m in Sources */,
137327E81AA5CF210034F82E /* RCTTabBarItem.m in Sources */,
13E067551A70F44B002CDEE1 /* RCTShadowView.m in Sources */, 13E067551A70F44B002CDEE1 /* RCTShadowView.m in Sources */,
13B0801A1A69489C00A75B9A /* RCTNavigator.m in Sources */, 13B0801A1A69489C00A75B9A /* RCTNavigator.m in Sources */,
830BA4551A8E3BDA00D53203 /* RCTCache.m in Sources */, 830BA4551A8E3BDA00D53203 /* RCTCache.m in Sources */,
137327E71AA5CF210034F82E /* RCTTabBar.m in Sources */,
134FCB3E1A6E7F0800051CC8 /* RCTWebViewExecutor.m in Sources */, 134FCB3E1A6E7F0800051CC8 /* RCTWebViewExecutor.m in Sources */,
13B0801C1A69489C00A75B9A /* RCTNavItem.m in Sources */, 13B0801C1A69489C00A75B9A /* RCTNavItem.m in Sources */,
83CBBA691A601EF300E9B192 /* RCTEventDispatcher.m in Sources */, 83CBBA691A601EF300E9B192 /* RCTEventDispatcher.m in Sources */,
13E0674A1A70F434002CDEE1 /* RCTUIManager.m in Sources */, 13E0674A1A70F434002CDEE1 /* RCTUIManager.m in Sources */,
1302F0FE1A78550100EBEF02 /* RCTStaticImageManager.m in Sources */,
13B0801B1A69489C00A75B9A /* RCTNavigatorManager.m in Sources */, 13B0801B1A69489C00A75B9A /* RCTNavigatorManager.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;

View File

@ -41,7 +41,6 @@ NSInteger kNeverProgressed = -10000;
@end @end
/** /**
* In general, `RCTNavigator` examines `_currentViews` (which are React child * In general, `RCTNavigator` examines `_currentViews` (which are React child
* views), and compares them to `_navigationController.viewControllers` (which * views), and compares them to `_navigationController.viewControllers` (which
@ -138,7 +137,6 @@ NSInteger kNeverProgressed = -10000;
return self; return self;
} }
/** /**
* Invoked when either a navigation item has been popped off, or when a * Invoked when either a navigation item has been popped off, or when a
* swipe-back gesture has began. The swipe-back gesture doesn't respect the * swipe-back gesture has began. The swipe-back gesture doesn't respect the
@ -184,7 +182,6 @@ NSInteger kNeverProgressed = -10000;
@end @end
@interface RCTNavigator() <RCTWrapperViewControllerNavigationListener, UINavigationControllerDelegate> @interface RCTNavigator() <RCTWrapperViewControllerNavigationListener, UINavigationControllerDelegate>
{ {
RCTEventDispatcher *_eventDispatcher; RCTEventDispatcher *_eventDispatcher;
@ -204,7 +201,7 @@ NSInteger kNeverProgressed = -10000;
* *
* - The run loop retains the displayLink. * - The run loop retains the displayLink.
* - `displayLink` retains its target. * - `displayLink` retains its target.
* - We use `reactWillDestroy` to remove the `RCTNavigator`'s reference to the * - We use `invalidate` to remove the `RCTNavigator`'s reference to the
* `displayLink` and remove the `displayLink` from the run loop. * `displayLink` and remove the `displayLink` from the run loop.
* *
* *
@ -212,7 +209,7 @@ NSInteger kNeverProgressed = -10000;
* -------------- * --------------
* *
* - Even though we could implement the `displayLink` cleanup without the * - Even though we could implement the `displayLink` cleanup without the
* `reactWillDestroy` hook by adding and removing it from the run loop at the * `invalidate` hook by adding and removing it from the run loop at the
* right times (begin/end animation), we need to account for the possibility * right times (begin/end animation), we need to account for the possibility
* that the view itself is destroyed mid-interaction. So we always keep it * that the view itself is destroyed mid-interaction. So we always keep it
* added to the run loop, but start/stop it with interactions/animations. We * added to the run loop, but start/stop it with interactions/animations. We
@ -343,7 +340,7 @@ NSInteger kNeverProgressed = -10000;
NSUInteger indexOfFrom = [_currentViews indexOfObject:fromController.navItem]; NSUInteger indexOfFrom = [_currentViews indexOfObject:fromController.navItem];
NSUInteger indexOfTo = [_currentViews indexOfObject:toController.navItem]; NSUInteger indexOfTo = [_currentViews indexOfObject:toController.navItem];
CGFloat destination = indexOfFrom < indexOfTo ? 1.0 : -1.0; CGFloat destination = indexOfFrom < indexOfTo ? 1.0 : -1.0;
_dummyView.frame = (CGRect){destination}; _dummyView.frame = (CGRect){{destination}};
_currentlyTransitioningFrom = indexOfFrom; _currentlyTransitioningFrom = indexOfFrom;
_currentlyTransitioningTo = indexOfTo; _currentlyTransitioningTo = indexOfTo;
if (indexOfFrom != indexOfTo) { if (indexOfFrom != indexOfTo) {
@ -450,24 +447,10 @@ NSInteger kNeverProgressed = -10000;
return self.superview ? self.superview : self.reactNavSuperviewLink; return self.superview ? self.superview : self.reactNavSuperviewLink;
} }
- (void)addControllerToClosestParent:(UIViewController *)controller
{
if (!controller.parentViewController) {
id responder = [self.superview nextResponder];
while (responder && ![responder isKindOfClass:[UIViewController class]]) {
responder = [responder nextResponder];
}
if (responder) {
[responder addChildViewController:controller];
[controller didMoveToParentViewController:responder];
}
}
}
- (void)reactBridgeDidFinishTransaction - (void)reactBridgeDidFinishTransaction
{ {
// we can't hook up the VC hierarchy in 'init' because the subviews aren't hooked up yet, // we can't hook up the VC hierarchy in 'init' because the subviews aren't
// so we do it on demand here // hooked up yet, so we do it on demand here
[self addControllerToClosestParent:_navigationController]; [self addControllerToClosestParent:_navigationController];
NSInteger viewControllerCount = _navigationController.viewControllers.count; NSInteger viewControllerCount = _navigationController.viewControllers.count;

View File

@ -2,9 +2,9 @@
#import "RCTNavigatorManager.h" #import "RCTNavigatorManager.h"
#import "RCTBridge.h"
#import "RCTConvert.h" #import "RCTConvert.h"
#import "RCTNavigator.h" #import "RCTNavigator.h"
#import "RCTShadowView.h"
#import "RCTSparseArray.h" #import "RCTSparseArray.h"
#import "RCTUIManager.h" #import "RCTUIManager.h"
@ -12,7 +12,7 @@
- (UIView *)view - (UIView *)view
{ {
return [[RCTNavigator alloc] initWithEventDispatcher:self.eventDispatcher]; return [[RCTNavigator alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
} }
RCT_EXPORT_VIEW_PROPERTY(requestedTopOfStack) RCT_EXPORT_VIEW_PROPERTY(requestedTopOfStack)
@ -34,7 +34,6 @@ RCT_EXPORT_VIEW_PROPERTY(requestedTopOfStack)
RCT_EXPORT(); RCT_EXPORT();
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){ [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
if (reactTag) {
RCTNavigator *navigator = viewRegistry[reactTag]; RCTNavigator *navigator = viewRegistry[reactTag];
if ([navigator isKindOfClass:[RCTNavigator class]]) { if ([navigator isKindOfClass:[RCTNavigator class]]) {
BOOL wasAcquired = [navigator requestSchedulingJavaScriptNavigation]; BOOL wasAcquired = [navigator requestSchedulingJavaScriptNavigation];
@ -42,9 +41,6 @@ RCT_EXPORT_VIEW_PROPERTY(requestedTopOfStack)
} else { } else {
RCTLogError(@"Cannot set lock: %@ (tag #%@) is not an RCTNavigator", navigator, reactTag); RCTLogError(@"Cannot set lock: %@ (tag #%@) is not an RCTNavigator", navigator, reactTag);
} }
} else {
RCTLogError(@"Tag not specified for requestSchedulingJavaScriptNavigation");
}
}]; }];
} }

View File

@ -2,6 +2,7 @@
#import "RCTScrollViewManager.h" #import "RCTScrollViewManager.h"
#import "RCTBridge.h"
#import "RCTConvert.h" #import "RCTConvert.h"
#import "RCTScrollView.h" #import "RCTScrollView.h"
@ -9,7 +10,7 @@
- (UIView *)view - (UIView *)view
{ {
return [[RCTScrollView alloc] initWithEventDispatcher:self.eventDispatcher]; return [[RCTScrollView alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
} }
RCT_EXPORT_VIEW_PROPERTY(alwaysBounceHorizontal) RCT_EXPORT_VIEW_PROPERTY(alwaysBounceHorizontal)

View File

@ -325,6 +325,11 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
return _reactSubviews; return _reactSubviews;
} }
- (RCTShadowView *)reactSuperview
{
return _superview;
}
- (NSNumber *)reactTagAtPoint:(CGPoint)point - (NSNumber *)reactTagAtPoint:(CGPoint)point
{ {
for (RCTShadowView *shadowView in _reactSubviews) { for (RCTShadowView *shadowView in _reactSubviews) {

View File

@ -0,0 +1,11 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import <UIKit/UIKit.h>
@class RCTEventDispatcher;
@interface RCTTabBar : UIView
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;
@end

139
ReactKit/Views/RCTTabBar.m Normal file
View File

@ -0,0 +1,139 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import "RCTTabBar.h"
#import "RCTEventDispatcher.h"
#import "RCTLog.h"
#import "RCTTabBarItem.h"
#import "RCTUtils.h"
#import "RCTView.h"
#import "RCTViewControllerProtocol.h"
#import "RCTWrapperViewController.h"
#import "UIView+ReactKit.h"
@interface RKCustomTabBarController : UITabBarController <RCTViewControllerProtocol>
@end
@implementation RKCustomTabBarController
@synthesize currentTopLayoutGuide = _currentTopLayoutGuide;
@synthesize currentBottomLayoutGuide = _currentBottomLayoutGuide;
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
_currentTopLayoutGuide = self.topLayoutGuide;
_currentBottomLayoutGuide = self.bottomLayoutGuide;
}
@end
@interface RCTTabBar() <UITabBarControllerDelegate>
@end
@implementation RCTTabBar
{
BOOL _tabsChanged;
RCTEventDispatcher *_eventDispatcher;
UITabBarController *_tabController;
NSMutableArray *_tabViews;
}
- (id)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
{
if ((self = [super initWithFrame:CGRectZero])) {
_eventDispatcher = eventDispatcher;
_tabViews = [[NSMutableArray alloc] init];
_tabController = [[RKCustomTabBarController alloc] init];
_tabController.delegate = self;
[self addSubview:_tabController.view];
}
return self;
}
- (UIViewController *)backingViewController
{
return _tabController;
}
- (void)dealloc
{
_tabController.delegate = nil;
}
- (NSArray *)reactSubviews
{
return _tabViews;
}
- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
{
if (![view isKindOfClass:[RCTTabBarItem class]]) {
RCTLogError(@"subview should be of type RCTTabBarItem");
return;
}
[_tabViews insertObject:view atIndex:atIndex];
_tabsChanged = YES;
}
- (void)removeReactSubview:(UIView *)subview
{
if (_tabViews.count == 0) {
RCTLogError(@"should have at least one view to remove a subview");
return;
}
[_tabViews removeObject:subview];
_tabsChanged = YES;
}
- (void)layoutSubviews
{
[super layoutSubviews];
_tabController.view.frame = self.bounds;
}
- (void)reactBridgeDidFinishTransaction
{
// we can't hook up the VC hierarchy in 'init' because the subviews aren't
// hooked up yet, so we do it on demand here whenever a transaction has finished
[self addControllerToClosestParent:_tabController];
//[RCTView addViewController:_tabController toBackingViewControllerForView:self];
if (_tabsChanged) {
NSMutableArray *viewControllers = [NSMutableArray array];
for (RCTTabBarItem *tab in [self reactSubviews]) {
UIViewController *controller = tab.backingViewController;
if (!controller) {
controller = [[RCTWrapperViewController alloc] initWithContentView:tab
eventDispatcher:_eventDispatcher];
}
[viewControllers addObject:controller];
}
_tabController.viewControllers = viewControllers;
_tabsChanged = NO;
}
[[self reactSubviews] enumerateObjectsUsingBlock:^(RCTTabBarItem *tab, NSUInteger index, BOOL *stop) {
UIViewController *controller = _tabController.viewControllers[index];
controller.tabBarItem = tab.barItem;
if (tab.selected) {
_tabController.selectedViewController = controller;
}
}];
}
#pragma mark - UITabBarControllerDelegate
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
NSUInteger index = [tabBarController.viewControllers indexOfObject:viewController];
RCTTabBarItem *tab = [self reactSubviews][index];
[_eventDispatcher sendInputEventWithName:@"topTap" body:@{@"target": tab.reactTag}];
return NO;
}
@end

View File

@ -0,0 +1,11 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import <UIKit/UIKit.h>
@interface RCTTabBarItem : UIView
@property (nonatomic, copy) NSString *icon;
@property (nonatomic, assign, getter=isSelected) BOOL selected;
@property (nonatomic, readonly) UITabBarItem *barItem;
@end

View File

@ -0,0 +1,83 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import "RCTTabBarItem.h"
#import "RCTConvert.h"
#import "RCTLog.h"
#import "UIView+ReactKit.h"
@implementation RCTTabBarItem
@synthesize barItem = _barItem;
- (UITabBarItem *)barItem
{
if (!_barItem) {
_barItem = [[UITabBarItem alloc] init];
}
return _barItem;
}
- (void)setIcon:(NSString *)icon
{
static NSDictionary *systemIcons;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
systemIcons = @{
@"more": @(UITabBarSystemItemMore),
@"favorites": @(UITabBarSystemItemFavorites),
@"featured": @(UITabBarSystemItemFeatured),
@"topRated": @(UITabBarSystemItemTopRated),
@"recents": @(UITabBarSystemItemRecents),
@"contacts": @(UITabBarSystemItemContacts),
@"history": @(UITabBarSystemItemHistory),
@"bookmarks": @(UITabBarSystemItemBookmarks),
@"search": @(UITabBarSystemItemSearch),
@"downloads": @(UITabBarSystemItemDownloads),
@"mostRecent": @(UITabBarSystemItemMostRecent),
@"mostViewed": @(UITabBarSystemItemMostViewed),
};
});
// Update icon
BOOL wasSystemIcon = (systemIcons[_icon] != nil);
_icon = [icon copy];
// Check if string matches any custom images first
UIImage *image = [RCTConvert UIImage:_icon];
UITabBarItem *oldItem = _barItem;
if (image) {
// Recreate barItem if previous item was a system icon
if (wasSystemIcon) {
_barItem = nil;
self.barItem.image = image;
} else {
self.barItem.image = image;
return;
}
} else {
// Not a custom image, may be a system item?
NSNumber *systemIcon = systemIcons[icon];
if (!systemIcon) {
RCTLogError(@"The tab bar icon '%@' did not match any known image or system icon", icon);
return;
}
_barItem = [[UITabBarItem alloc] initWithTabBarSystemItem:[systemIcon integerValue] tag:oldItem.tag];
}
// Reapply previous properties
_barItem.title = oldItem.title;
_barItem.imageInsets = oldItem.imageInsets;
_barItem.selectedImage = oldItem.selectedImage;
_barItem.badgeValue = oldItem.badgeValue;
}
- (UIViewController *)backingViewController
{
return self.superview.backingViewController;
}
@end

View File

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

View File

@ -0,0 +1,25 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import "RCTTabBarItemManager.h"
#import "RCTConvert.h"
#import "RCTTabBarItem.h"
@implementation RCTTabBarItemManager
- (UIView *)view
{
return [[RCTTabBarItem alloc] init];
}
RCT_EXPORT_VIEW_PROPERTY(selected);
RCT_EXPORT_VIEW_PROPERTY(icon);
RCT_REMAP_VIEW_PROPERTY(selectedIcon, barItem.selectedImage);
RCT_REMAP_VIEW_PROPERTY(badgeValue, barItem.badgeValue);
RCT_CUSTOM_VIEW_PROPERTY(title, RCTTabBarItem *)
{
view.barItem.title = json ? [RCTConvert NSString:json] : defaultView.barItem.title;
view.barItem.imageInsets = [view.barItem.title length] ? UIEdgeInsetsZero : (UIEdgeInsets){6, 0, -6, 0};
}
@end

View File

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

View File

@ -0,0 +1,17 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import "RCTTabBarManager.h"
#import "RCTBridge.h"
#import "RCTTabBar.h"
@implementation RCTTabBarManager
@synthesize bridge = _bridge;
- (UIView *)view
{
return [[RCTTabBar alloc] initWithEventDispatcher:_bridge.eventDispatcher];
}
@end

View File

@ -11,7 +11,7 @@
- (UIView *)view - (UIView *)view
{ {
return [[RCTTextField alloc] initWithEventDispatcher:self.eventDispatcher]; return [[RCTTextField alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
} }
RCT_EXPORT_VIEW_PROPERTY(caretHidden) RCT_EXPORT_VIEW_PROPERTY(caretHidden)

View File

@ -10,14 +10,18 @@
@interface RCTView : UIView @interface RCTView : UIView
/**
* Used to control how touch events are processed.
*/
@property (nonatomic, assign) RCTPointerEvents pointerEvents; @property (nonatomic, assign) RCTPointerEvents pointerEvents;
+ (void)autoAdjustInsetsForView:(UIView<RCTAutoInsetsProtocol> *)parentView + (void)autoAdjustInsetsForView:(UIView<RCTAutoInsetsProtocol> *)parentView
withScrollView:(UIScrollView *)scrollView withScrollView:(UIScrollView *)scrollView
updateOffset:(BOOL)updateOffset; updateOffset:(BOOL)updateOffset;
+ (UIViewController *)backingViewControllerForView:(UIView *)view; /**
* Find the first view controller whose view, or any subview is the specified view.
*/
+ (UIEdgeInsets)contentInsetsForView:(UIView *)curView; + (UIEdgeInsets)contentInsetsForView:(UIView *)curView;
@end @end

View File

@ -5,6 +5,7 @@
#import "RCTAutoInsetsProtocol.h" #import "RCTAutoInsetsProtocol.h"
#import "RCTConvert.h" #import "RCTConvert.h"
#import "RCTLog.h" #import "RCTLog.h"
#import "UIView+ReactKit.h"
static NSString *RCTRecursiveAccessibilityLabel(UIView *view) static NSString *RCTRecursiveAccessibilityLabel(UIView *view)
{ {
@ -23,15 +24,6 @@ static NSString *RCTRecursiveAccessibilityLabel(UIView *view)
@implementation RCTView @implementation RCTView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_pointerEvents = RCTPointerEventsUnspecified;
}
return self;
}
- (NSString *)accessibilityLabel - (NSString *)accessibilityLabel
{ {
if (super.accessibilityLabel) { if (super.accessibilityLabel) {
@ -108,19 +100,10 @@ static NSString *RCTRecursiveAccessibilityLabel(UIView *view)
} }
} }
+ (UIViewController *)backingViewControllerForView:(UIView *)view
{
id responder = [view nextResponder];
if ([responder isKindOfClass:[UIViewController class]]) {
return responder;
}
return nil;
}
+ (UIEdgeInsets)contentInsetsForView:(UIView *)view + (UIEdgeInsets)contentInsetsForView:(UIView *)view
{ {
while (view) { while (view) {
UIViewController *controller = [self backingViewControllerForView:view]; UIViewController *controller = view.backingViewController;
if (controller) { if (controller) {
return (UIEdgeInsets){ return (UIEdgeInsets){
controller.topLayoutGuide.length, 0, controller.topLayoutGuide.length, 0,

View File

@ -0,0 +1,13 @@
// Copyright 2004-present Facebook. All Rights Reserved.
/**
* A simple protocol that any React-managed ViewControllers should implement.
* We need all of our ViewControllers to cache layoutGuide changes so any View
* in our View hierarchy can access accurate layoutGuide info at any time.
*/
@protocol RCTViewControllerProtocol <NSObject>
@property (nonatomic, readonly, strong) id<UILayoutSupport> currentTopLayoutGuide;
@property (nonatomic, readonly, strong) id<UILayoutSupport> currentBottomLayoutGuide;
@end

View File

@ -23,14 +23,6 @@ typedef void (^RCTViewManagerUIBlock)(RCTUIManager *uiManager, RCTSparseArray *v
*/ */
@property (nonatomic, strong) RCTBridge *bridge; @property (nonatomic, strong) RCTBridge *bridge;
/**
* The event dispatcher is used to send events back to the JavaScript application.
* It can either be used directly by the module, or passed on to instantiated
* view subclasses so that they can handle their own events.
*/
// TODO: remove this, as it can be accessed directly from bridge
@property (nonatomic, readonly) RCTEventDispatcher *eventDispatcher;
/** /**
* The module name exposed to React JS. If omitted, this will be inferred * The module name exposed to React JS. If omitted, this will be inferred
* automatically by using the view module's class name. It is better to not * automatically by using the view module's class name. It is better to not

View File

@ -14,11 +14,6 @@
@synthesize bridge = _bridge; @synthesize bridge = _bridge;
- (RCTEventDispatcher *)eventDispatcher
{
return _bridge.eventDispatcher;
}
+ (NSString *)moduleName + (NSString *)moduleName
{ {
// Default implementation, works in most cases // Default implementation, works in most cases

View File

@ -13,6 +13,7 @@
- (void)insertReactSubview:(id<RCTViewNodeProtocol>)subview atIndex:(NSInteger)atIndex; - (void)insertReactSubview:(id<RCTViewNodeProtocol>)subview atIndex:(NSInteger)atIndex;
- (void)removeReactSubview:(id<RCTViewNodeProtocol>)subview; - (void)removeReactSubview:(id<RCTViewNodeProtocol>)subview;
- (NSMutableArray *)reactSubviews; - (NSMutableArray *)reactSubviews;
- (id<RCTViewNodeProtocol>)reactSuperview;
- (NSNumber *)reactTagAtPoint:(CGPoint)point; - (NSNumber *)reactTagAtPoint:(CGPoint)point;
// View is an RCTRootView // View is an RCTRootView
@ -26,3 +27,9 @@
- (void)reactBridgeDidFinishTransaction; - (void)reactBridgeDidFinishTransaction;
@end @end
// TODO: this is kinda dumb - let's come up with a
// better way of identifying root react views please!
static inline BOOL RCTIsReactRootView(NSNumber *reactTag) {
return reactTag.integerValue % 10 == 1;
}

View File

@ -2,6 +2,8 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "RCTViewControllerProtocol.h"
@class RCTEventDispatcher; @class RCTEventDispatcher;
@class RCTNavItem; @class RCTNavItem;
@class RCTWrapperViewController; @class RCTWrapperViewController;
@ -13,7 +15,7 @@ didMoveToNavigationController:(UINavigationController *)navigationController;
@end @end
@interface RCTWrapperViewController : UIViewController @interface RCTWrapperViewController : UIViewController <RCTViewControllerProtocol>
- (instancetype)initWithContentView:(UIView *)contentView - (instancetype)initWithContentView:(UIView *)contentView
eventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER; eventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;
@ -21,7 +23,7 @@ didMoveToNavigationController:(UINavigationController *)navigationController;
- (instancetype)initWithNavItem:(RCTNavItem *)navItem - (instancetype)initWithNavItem:(RCTNavItem *)navItem
eventDispatcher:(RCTEventDispatcher *)eventDispatcher; eventDispatcher:(RCTEventDispatcher *)eventDispatcher;
@property (nonatomic, readwrite, weak) id<RCTWrapperViewControllerNavigationListener> navigationListener; @property (nonatomic, weak) id<RCTWrapperViewControllerNavigationListener> navigationListener;
@property (nonatomic, strong, readwrite) RCTNavItem *navItem; @property (nonatomic, strong) RCTNavItem *navItem;
@end @end

View File

@ -2,22 +2,30 @@
#import "RCTWrapperViewController.h" #import "RCTWrapperViewController.h"
#import <UIKit/UIScrollView.h>
#import "RCTEventDispatcher.h" #import "RCTEventDispatcher.h"
#import "RCTNavItem.h" #import "RCTNavItem.h"
#import "RCTUtils.h" #import "RCTUtils.h"
#import "RCTViewControllerProtocol.h"
#import "UIView+ReactKit.h" #import "UIView+ReactKit.h"
@implementation RCTWrapperViewController @implementation RCTWrapperViewController
{ {
UIView *_wrapperView;
UIView *_contentView; UIView *_contentView;
RCTEventDispatcher *_eventDispatcher; RCTEventDispatcher *_eventDispatcher;
CGFloat _previousTopLayout; CGFloat _previousTopLayout;
CGFloat _previousBottomLayout; CGFloat _previousBottomLayout;
} }
- (instancetype)initWithContentView:(UIView *)contentView eventDispatcher:(RCTEventDispatcher *)eventDispatcher @synthesize currentTopLayoutGuide = _currentTopLayoutGuide;
@synthesize currentBottomLayoutGuide = _currentBottomLayoutGuide;
- (instancetype)initWithContentView:(UIView *)contentView
eventDispatcher:(RCTEventDispatcher *)eventDispatcher
{ {
if ((self = [super initWithNibName:nil bundle:nil])) { if (self = [super initWithNibName:nil bundle:nil]) {
_contentView = contentView; _contentView = contentView;
_eventDispatcher = eventDispatcher; _eventDispatcher = eventDispatcher;
self.automaticallyAdjustsScrollViewInsets = NO; self.automaticallyAdjustsScrollViewInsets = NO;
@ -25,18 +33,31 @@
return self; return self;
} }
- (instancetype)initWithNavItem:(RCTNavItem *)navItem eventDispatcher:(RCTEventDispatcher *)eventDispatcher - (instancetype)initWithNavItem:(RCTNavItem *)navItem
eventDispatcher:(RCTEventDispatcher *)eventDispatcher
{ {
if ((self = [self initWithContentView:navItem eventDispatcher:eventDispatcher])) { if (self = [self initWithContentView:navItem eventDispatcher:eventDispatcher]) {
_navItem = navItem; _navItem = navItem;
} }
return self; return self;
} }
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
_currentTopLayoutGuide = self.topLayoutGuide;
_currentBottomLayoutGuide = self.bottomLayoutGuide;
}
- (void)viewWillAppear:(BOOL)animated - (void)viewWillAppear:(BOOL)animated
{ {
[super viewWillAppear:animated]; [super viewWillAppear:animated];
// TODO: find a way to make this less-tightly coupled to navigation controller
if ([self.parentViewController isKindOfClass:[UINavigationController class]])
{
[self.navigationController setNavigationBarHidden:!_navItem animated:animated]; [self.navigationController setNavigationBarHidden:!_navItem animated:animated];
if (!_navItem) { if (!_navItem) {
return; return;
@ -44,27 +65,6 @@
self.navigationItem.title = _navItem.title; self.navigationItem.title = _navItem.title;
[self _configureNavBarStyle];
if (_navItem.rightButtonTitle.length > 0) {
self.navigationItem.rightBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:_navItem.rightButtonTitle
style:UIBarButtonItemStyleDone
target:self
action:@selector(rightButtonTapped)];
}
if (_navItem.backButtonTitle.length > 0) {
self.navigationItem.backBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:_navItem.backButtonTitle
style:UIBarButtonItemStylePlain
target:nil
action:nil];
}
}
- (void)_configureNavBarStyle
{
UINavigationBar *bar = self.navigationController.navigationBar; UINavigationBar *bar = self.navigationController.navigationBar;
if (_navItem.barTintColor) { if (_navItem.barTintColor) {
bar.barTintColor = _navItem.barTintColor; bar.barTintColor = _navItem.barTintColor;
@ -78,27 +78,46 @@
if (_navItem.titleTextColor) { if (_navItem.titleTextColor) {
[bar setTitleTextAttributes:@{NSForegroundColorAttributeName : _navItem.titleTextColor}]; [bar setTitleTextAttributes:@{NSForegroundColorAttributeName : _navItem.titleTextColor}];
} }
if (_navItem.rightButtonTitle.length > 0) {
self.navigationItem.rightBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:_navItem.rightButtonTitle
style:UIBarButtonItemStyleDone
target:self
action:@selector(handleNavRightButtonTapped)];
}
if (_navItem.backButtonTitle.length > 0) {
self.navigationItem.backBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:_navItem.backButtonTitle
style:UIBarButtonItemStylePlain
target:nil
action:nil];
}
}
} }
- (void)loadView - (void)loadView
{ {
// Add a wrapper so that UIViewControllerWrapperView (managed by the // add a wrapper so that UIViewControllerWrapperView (managed by the
// UINavigationController) doesn't end up resetting the frames for // UINavigationController) doesn't end up resetting the frames for
// `contentView` which is a react-managed view. //`contentView` which is a react-managed view.
self.view = [[UIView alloc] init]; _wrapperView = [[UIView alloc] initWithFrame:_contentView.bounds];
[self.view addSubview:_contentView]; [_wrapperView addSubview:_contentView];
self.view = _wrapperView;
} }
- (void)rightButtonTapped - (void)handleNavRightButtonTapped
{ {
[_eventDispatcher sendInputEventWithName:@"topNavRightButtonTap" body:@{@"target":_navItem.reactTag}]; [_eventDispatcher sendInputEventWithName:@"topNavRightButtonTap"
body:@{@"target":_navItem.reactTag}];
} }
- (void)didMoveToParentViewController:(UIViewController *)parent - (void)didMoveToParentViewController:(UIViewController *)parent
{ {
// There's no clear setter for navigation controllers, but did move to parent view controller // There's no clear setter for navigation controllers, but did move to parent
// provides the desired effect. This is called after a pop finishes, be it a swipe to go back // view controller provides the desired effect. This is called after a pop
// or a standard tap on the back button // finishes, be it a swipe to go back or a standard tap on the back button
[super didMoveToParentViewController:parent]; [super didMoveToParentViewController:parent];
if (parent == nil || [parent isKindOfClass:[UINavigationController class]]) { if (parent == nil || [parent isKindOfClass:[UINavigationController class]]) {
[self.navigationListener wrapperViewController:self didMoveToNavigationController:(UINavigationController *)parent]; [self.navigationListener wrapperViewController:self didMoveToNavigationController:(UINavigationController *)parent];

View File

@ -8,4 +8,17 @@
@interface UIView (ReactKit) <RCTViewNodeProtocol> @interface UIView (ReactKit) <RCTViewNodeProtocol>
/**
* This method finds and returns the containing view controller for the view.
*/
- (UIViewController *)backingViewController;
/**
* This method attaches the specified controller as a child of the
* the owning view controller of this view. Returns NO if no view
* controller is found (which may happen if the view is not currently
* attached to the view hierarchy).
*/
- (void)addControllerToClosestParent:(UIViewController *)controller;
@end @end

View File

@ -5,6 +5,7 @@
#import <objc/runtime.h> #import <objc/runtime.h>
#import "RCTAssert.h" #import "RCTAssert.h"
#import "RCTWrapperViewController.h"
@implementation UIView (ReactKit) @implementation UIView (ReactKit)
@ -20,7 +21,7 @@
- (BOOL)isReactRootView - (BOOL)isReactRootView
{ {
return NO; return RCTIsReactRootView(self.reactTag);
} }
- (NSNumber *)reactTagAtPoint:(CGPoint)point - (NSNumber *)reactTagAtPoint:(CGPoint)point
@ -39,7 +40,7 @@
- (void)removeReactSubview:(UIView *)subview - (void)removeReactSubview:(UIView *)subview
{ {
RCTAssert(subview.superview == self, @""); RCTAssert(subview.superview == self, @"%@ is a not a subview of %@", subview, self);
[subview removeFromSuperview]; [subview removeFromSuperview];
} }
@ -48,4 +49,34 @@
return self.subviews; return self.subviews;
} }
- (UIView *)reactSuperview
{
return self.superview;
}
- (UIViewController *)backingViewController
{
id responder = [self nextResponder];
if ([responder isKindOfClass:[RCTWrapperViewController class]]) {
return responder;
}
return nil;
}
- (void)addControllerToClosestParent:(UIViewController *)controller
{
if (!controller.parentViewController) {
UIView *parentView = (UIView *)self.reactSuperview;
while (parentView) {
if (parentView.backingViewController) {
[parentView.backingViewController addChildViewController:controller];
[controller didMoveToParentViewController:parentView.backingViewController];
break;
}
parentView = (UIView *)parentView.reactSuperview;
}
return;
}
}
@end @end

View File

@ -29,10 +29,6 @@ var options = parseCommandLine([{
}, { }, {
command: 'root', command: 'root',
description: 'add another root(s) to be used by the packager in this project', description: 'add another root(s) to be used by the packager in this project',
}, {
command: 'dev',
default: true,
description: 'produce development packages with extra warnings enabled',
}]); }]);
if (!options.projectRoots) { if (!options.projectRoots) {
@ -97,7 +93,6 @@ function openStackFrameInEditor(req, res, next) {
function getAppMiddleware(options) { function getAppMiddleware(options) {
return ReactPackager.middleware({ return ReactPackager.middleware({
dev: options.dev,
projectRoots: options.projectRoots, projectRoots: options.projectRoots,
blacklistRE: blacklist(false), blacklistRE: blacklist(false),
cacheVersion: '2', cacheVersion: '2',
@ -106,7 +101,7 @@ function getAppMiddleware(options) {
} }
function runServer( function runServer(
options, /* {string projectRoot, bool web, bool dev} */ options, /* {[]string projectRoot, bool web} */
readyCallback readyCallback
) { ) {
var app = connect() var app = connect()

View File

@ -24,7 +24,6 @@ describe('HasteDependencyResolver', function() {
var depResolver = new HasteDependencyResolver({ var depResolver = new HasteDependencyResolver({
projectRoot: '/root', projectRoot: '/root',
dev: false,
}); });
// Is there a better way? How can I mock the prototype instead? // Is there a better way? How can I mock the prototype instead?
@ -36,7 +35,7 @@ describe('HasteDependencyResolver', function() {
return q(); return q();
}); });
return depResolver.getDependencies('/root/index.js') return depResolver.getDependencies('/root/index.js', { dev: false })
.then(function(result) { .then(function(result) {
expect(result.mainModuleId).toEqual('index'); expect(result.mainModuleId).toEqual('index');
expect(result.dependencies).toEqual([ expect(result.dependencies).toEqual([
@ -85,7 +84,6 @@ describe('HasteDependencyResolver', function() {
var depResolver = new HasteDependencyResolver({ var depResolver = new HasteDependencyResolver({
projectRoot: '/root', projectRoot: '/root',
dev: true,
}); });
// Is there a better way? How can I mock the prototype instead? // Is there a better way? How can I mock the prototype instead?
@ -97,7 +95,7 @@ describe('HasteDependencyResolver', function() {
return q(); return q();
}); });
return depResolver.getDependencies('/root/index.js') return depResolver.getDependencies('/root/index.js', { dev: true })
.then(function(result) { .then(function(result) {
expect(result.mainModuleId).toEqual('index'); expect(result.mainModuleId).toEqual('index');
expect(result.dependencies).toEqual([ expect(result.dependencies).toEqual([
@ -147,7 +145,6 @@ describe('HasteDependencyResolver', function() {
var depResolver = new HasteDependencyResolver({ var depResolver = new HasteDependencyResolver({
projectRoot: '/root', projectRoot: '/root',
polyfillModuleNames: ['some module'], polyfillModuleNames: ['some module'],
dev: false,
}); });
// Is there a better way? How can I mock the prototype instead? // Is there a better way? How can I mock the prototype instead?
@ -159,7 +156,7 @@ describe('HasteDependencyResolver', function() {
return q(); return q();
}); });
return depResolver.getDependencies('/root/index.js') return depResolver.getDependencies('/root/index.js', { dev: false })
.then(function(result) { .then(function(result) {
expect(result.mainModuleId).toEqual('index'); expect(result.mainModuleId).toEqual('index');
expect(result.dependencies).toEqual([ expect(result.dependencies).toEqual([
@ -218,7 +215,6 @@ describe('HasteDependencyResolver', function() {
it('should ', function() { it('should ', function() {
var depResolver = new HasteDependencyResolver({ var depResolver = new HasteDependencyResolver({
projectRoot: '/root', projectRoot: '/root',
dev: false,
}); });
var depGraph = depResolver._depGraph; var depGraph = depResolver._depGraph;

View File

@ -32,10 +32,6 @@ var validateOpts = declareOpts({
type: 'array', type: 'array',
default: [], default: [],
}, },
dev: {
type: 'boolean',
default: true,
},
nonPersistent: { nonPersistent: {
type: 'boolean', type: 'boolean',
default: false, default: false,
@ -62,20 +58,20 @@ function HasteDependencyResolver(options) {
fileWatcher: this._fileWatcher fileWatcher: this._fileWatcher
}); });
this._polyfillModuleNames = [
opts.dev this._polyfillModuleNames = opts.polyfillModuleNames || [];
? path.join(__dirname, 'polyfills/prelude_dev.js')
: path.join(__dirname, 'polyfills/prelude.js'),
path.join(__dirname, 'polyfills/require.js'),
path.join(__dirname, 'polyfills/polyfills.js'),
path.join(__dirname, 'polyfills/console.js'),
path.join(__dirname, 'polyfills/error-guard.js'),
].concat(
opts.polyfillModuleNames || []
);
} }
HasteDependencyResolver.prototype.getDependencies = function(main) { var getDependenciesValidateOpts = declareOpts({
dev: {
type: 'boolean',
default: true,
},
});
HasteDependencyResolver.prototype.getDependencies = function(main, options) {
var opts = getDependenciesValidateOpts(options);
var depGraph = this._depGraph; var depGraph = this._depGraph;
var self = this; var self = this;
@ -84,7 +80,7 @@ HasteDependencyResolver.prototype.getDependencies = function(main) {
var dependencies = depGraph.getOrderedDependencies(main); var dependencies = depGraph.getOrderedDependencies(main);
var mainModuleId = dependencies[0].id; var mainModuleId = dependencies[0].id;
self._prependPolyfillDependencies(dependencies); self._prependPolyfillDependencies(dependencies, opts.dev);
return { return {
mainModuleId: mainModuleId, mainModuleId: mainModuleId,
@ -94,10 +90,19 @@ HasteDependencyResolver.prototype.getDependencies = function(main) {
}; };
HasteDependencyResolver.prototype._prependPolyfillDependencies = function( HasteDependencyResolver.prototype._prependPolyfillDependencies = function(
dependencies dependencies,
isDev
) { ) {
var polyfillModuleNames = this._polyfillModuleNames; var polyfillModuleNames = [
if (polyfillModuleNames.length > 0) { isDev
? path.join(__dirname, 'polyfills/prelude_dev.js')
: path.join(__dirname, 'polyfills/prelude.js'),
path.join(__dirname, 'polyfills/require.js'),
path.join(__dirname, 'polyfills/polyfills.js'),
path.join(__dirname, 'polyfills/console.js'),
path.join(__dirname, 'polyfills/error-guard.js'),
].concat(this._polyfillModuleNames);
var polyfillModules = polyfillModuleNames.map( var polyfillModules = polyfillModuleNames.map(
function(polyfillModuleName, idx) { function(polyfillModuleName, idx) {
return new ModuleDescriptor({ return new ModuleDescriptor({
@ -109,7 +114,6 @@ HasteDependencyResolver.prototype._prependPolyfillDependencies = function(
} }
); );
dependencies.unshift.apply(dependencies, polyfillModules); dependencies.unshift.apply(dependencies, polyfillModules);
}
}; };
HasteDependencyResolver.prototype.wrapModule = function(module, code) { HasteDependencyResolver.prototype.wrapModule = function(module, code) {

View File

@ -34,10 +34,6 @@ var validateOpts = declareOpts({
type: 'boolean', type: 'boolean',
default: false, default: false,
}, },
dev: {
type: 'boolean',
default: true,
},
transformModulePath: { transformModulePath: {
type:'string', type:'string',
required: false, required: false,

View File

@ -7,6 +7,7 @@ var UglifyJS = require('uglify-js');
module.exports = Package; module.exports = Package;
function Package(sourceMapUrl) { function Package(sourceMapUrl) {
this._finalized = false;
this._modules = []; this._modules = [];
this._sourceMapUrl = sourceMapUrl; this._sourceMapUrl = sourceMapUrl;
} }
@ -40,23 +41,56 @@ Package.prototype.finalize = function(options) {
Object.freeze(this._modules); Object.freeze(this._modules);
Object.seal(this._modules); Object.seal(this._modules);
this._finalized = true;
}; };
Package.prototype.getSource = function(options) { Package.prototype._assertFinalized = function() {
if (!this._source) { if (!this._finalized) {
options = options || {}; throw new Error('Package need to be finalized before getting any source');
this._source = _.pluck(this._modules, 'transformedCode').join('\n');
if (options.inlineSourceMap) {
var sourceMap = this.getSourceMap({excludeSource: true});
this._source += '\nRAW_SOURCE_MAP = ' + JSON.stringify(sourceMap) + ';';
} }
this._source += '\n\/\/@ sourceMappingURL=' + this._sourceMapUrl; };
Package.prototype._getSource = function() {
if (this._source == null) {
this._source = _.pluck(this._modules, 'transformedCode').join('\n');
} }
return this._source; return this._source;
}; };
Package.prototype._getInlineSourceMap = function() {
if (this._inlineSourceMap == null) {
var sourceMap = this.getSourceMap({excludeSource: true});
this._inlineSourceMap = '\nRAW_SOURCE_MAP = ' +
JSON.stringify(sourceMap) + ';';
}
return this._inlineSourceMap;
};
Package.prototype.getSource = function(options) {
this._assertFinalized();
options = options || {};
if (options.minify) {
return this.getMinifiedSourceAndMap().code;
}
var source = this._getSource();
if (options.inlineSourceMap) {
source += this._getInlineSourceMap();
}
source += '\n\/\/@ sourceMappingURL=' + this._sourceMapUrl;
return source;
};
Package.prototype.getMinifiedSourceAndMap = function() { Package.prototype.getMinifiedSourceAndMap = function() {
var source = this.getSource({inlineSourceMap: false}); this._assertFinalized();
var source = this._getSource();
try { try {
return UglifyJS.minify(source, { return UglifyJS.minify(source, {
fromString: true, fromString: true,
@ -88,6 +122,8 @@ Package.prototype.getMinifiedSourceAndMap = function() {
}; };
Package.prototype.getSourceMap = function(options) { Package.prototype.getSourceMap = function(options) {
this._assertFinalized();
options = options || {}; options = options || {};
var mappings = this._getMappings(); var mappings = this._getMappings();
var map = { var map = {
@ -102,7 +138,6 @@ Package.prototype.getSourceMap = function(options) {
return map; return map;
}; };
Package.prototype._getMappings = function() { Package.prototype._getMappings = function() {
var modules = this._modules; var modules = this._modules;

View File

@ -36,10 +36,6 @@ var validateOpts = declareOpts({
type: 'boolean', type: 'boolean',
default: false, default: false,
}, },
dev: {
type: 'boolean',
default: true,
},
transformModulePath: { transformModulePath: {
type:'string', type:'string',
required: false, required: false,
@ -59,7 +55,6 @@ function Packager(options) {
projectRoots: opts.projectRoots, projectRoots: opts.projectRoots,
blacklistRE: opts.blacklistRE, blacklistRE: opts.blacklistRE,
polyfillModuleNames: opts.polyfillModuleNames, polyfillModuleNames: opts.polyfillModuleNames,
dev: opts.dev,
nonPersistent: opts.nonPersistent, nonPersistent: opts.nonPersistent,
moduleFormat: opts.moduleFormat moduleFormat: opts.moduleFormat
}); });
@ -69,7 +64,6 @@ function Packager(options) {
blacklistRE: opts.blacklistRE, blacklistRE: opts.blacklistRE,
cacheVersion: opts.cacheVersion, cacheVersion: opts.cacheVersion,
resetCache: opts.resetCache, resetCache: opts.resetCache,
dev: opts.dev,
transformModulePath: opts.transformModulePath, transformModulePath: opts.transformModulePath,
nonPersistent: opts.nonPersistent, nonPersistent: opts.nonPersistent,
}); });
@ -82,14 +76,14 @@ Packager.prototype.kill = function() {
]); ]);
}; };
Packager.prototype.package = function(main, runModule, sourceMapUrl) { Packager.prototype.package = function(main, runModule, sourceMapUrl, isDev) {
var transformModule = this._transformModule.bind(this); var transformModule = this._transformModule.bind(this);
var ppackage = new Package(sourceMapUrl); var ppackage = new Package(sourceMapUrl);
var findEventId = Activity.startEvent('find dependencies'); var findEventId = Activity.startEvent('find dependencies');
var transformEventId; var transformEventId;
return this.getDependencies(main) return this.getDependencies(main, isDev)
.then(function(result) { .then(function(result) {
Activity.endEvent(findEventId); Activity.endEvent(findEventId);
transformEventId = Activity.startEvent('transform'); transformEventId = Activity.startEvent('transform');
@ -119,8 +113,8 @@ Packager.prototype.invalidateFile = function(filePath) {
this._transformer.invalidateFile(filePath); this._transformer.invalidateFile(filePath);
}; };
Packager.prototype.getDependencies = function(main) { Packager.prototype.getDependencies = function(main, isDev) {
return this._resolver.getDependencies(main); return this._resolver.getDependencies(main, { dev: isDev });
}; };
Packager.prototype._transformModule = function(module) { Packager.prototype._transformModule = function(module) {

View File

@ -35,10 +35,6 @@ var validateOpts = declareOpts({
type: 'boolean', type: 'boolean',
default: false, default: false,
}, },
dev: {
type: 'boolean',
default: true,
},
transformModulePath: { transformModulePath: {
type:'string', type:'string',
required: false, required: false,
@ -51,7 +47,6 @@ var validateOpts = declareOpts({
function Server(options) { function Server(options) {
var opts = validateOpts(options); var opts = validateOpts(options);
this._dev = opts.dev;
this._projectRoots = opts.projectRoots; this._projectRoots = opts.projectRoots;
this._packages = Object.create(null); this._packages = Object.create(null);
this._packager = new Packager(opts); this._packager = new Packager(opts);
@ -73,14 +68,16 @@ Server.prototype._onFileChange = function(type, filepath, root) {
}; };
Server.prototype._rebuildPackages = function() { Server.prototype._rebuildPackages = function() {
var dev = this._dev;
var buildPackage = this._buildPackage.bind(this); var buildPackage = this._buildPackage.bind(this);
var packages = this._packages; var packages = this._packages;
Object.keys(packages).forEach(function(key) { Object.keys(packages).forEach(function(key) {
var options = getOptionsFromUrl(key); var options = getOptionsFromUrl(key);
packages[key] = buildPackage(options).then(function(p) { packages[key] = buildPackage(options).then(function(p) {
// Make a throwaway call to getSource to cache the source string. // Make a throwaway call to getSource to cache the source string.
p.getSource({inlineSourceMap: dev}); p.getSource({
inlineSourceMap: options.dev,
minify: options.minify,
});
return p; return p;
}); });
}); });
@ -97,7 +94,8 @@ Server.prototype._buildPackage = function(options) {
return this._packager.package( return this._packager.package(
options.main, options.main,
options.runModule, options.runModule,
options.sourceMapUrl options.sourceMapUrl,
options.dev
); );
}; };
@ -166,11 +164,13 @@ Server.prototype.processRequest = function(req, res, next) {
var building = this._packages[req.url] || this._buildPackage(options); var building = this._packages[req.url] || this._buildPackage(options);
this._packages[req.url] = building; this._packages[req.url] = building;
var dev = this._dev;
building.then( building.then(
function(p) { function(p) {
if (requestType === 'bundle') { if (requestType === 'bundle') {
res.end(p.getSource({inlineSourceMap: dev})); res.end(p.getSource({
inlineSourceMap: options.dev,
minify: options.minify,
}));
Activity.endEvent(startReqEventId); Activity.endEvent(startReqEventId);
} else if (requestType === 'map') { } else if (requestType === 'map') {
res.end(JSON.stringify(p.getSourceMap())); res.end(JSON.stringify(p.getSourceMap()));
@ -196,8 +196,9 @@ function getOptionsFromUrl(reqUrl) {
return { return {
sourceMapUrl: urlObj.pathname.replace(/\.bundle$/, '.map'), sourceMapUrl: urlObj.pathname.replace(/\.bundle$/, '.map'),
main: main, main: main,
runModule: urlObj.query.runModule === 'true' || dev: getBoolOptionFromQuery(urlObj.query, 'dev'),
urlObj.query.runModule === '1' || minify: getBoolOptionFromQuery(urlObj.query, 'minify'),
runModule: getBoolOptionFromQuery(urlObj.query, 'runModule') ||
// Backwards compatibility. // Backwards compatibility.
urlObj.pathname.split('.').some(function(part) { urlObj.pathname.split('.').some(function(part) {
return part === 'runModule'; return part === 'runModule';
@ -205,6 +206,10 @@ function getOptionsFromUrl(reqUrl) {
}; };
} }
function getBoolOptionFromQuery(query, opt) {
return query[opt] === 'true' || query[opt] === '1';
}
function handleError(res, error) { function handleError(res, error) {
res.writeHead(500, { res.writeHead(500, {
'Content-Type': 'application/json; charset=UTF-8', 'Content-Type': 'application/json; charset=UTF-8',

View File

@ -42,6 +42,8 @@ module.exports = function(descriptor) {
var schema = Joi.object().keys(joiKeys); var schema = Joi.object().keys(joiKeys);
return function(opts) { return function(opts) {
opts = opts || {};
var res = Joi.validate(opts, schema, { var res = Joi.validate(opts, schema, {
abortEarly: true, abortEarly: true,
allowUnknown: false, allowUnknown: false,