[React Native] Add preliminary animation API
This commit is contained in:
parent
b185cbd6e6
commit
fb475dd0c4
|
@ -0,0 +1,357 @@
|
||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 46;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||||
|
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||||
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||||
|
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||||
|
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
|
||||||
|
8323482C1A77B59500B55238 /* libReactKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832348291A77B50100B55238 /* libReactKit.a */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
||||||
|
remoteInfo = RCTText;
|
||||||
|
};
|
||||||
|
832348281A77B50100B55238 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 834D32361A76971A00F38302 /* ReactKit.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
|
||||||
|
remoteInfo = ReactKit;
|
||||||
|
};
|
||||||
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
13B07F961A680F5B00A75B9A /* 2048.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2048.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
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>"; };
|
||||||
|
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; 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>"; };
|
||||||
|
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||||
|
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
834D32361A76971A00F38302 /* ReactKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactKit.xcodeproj; path = ../../ReactKit/ReactKit.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
8323482C1A77B59500B55238 /* libReactKit.a in Frameworks */,
|
||||||
|
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
13B07FAE1A68108700A75B9A /* 2048 */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||||
|
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||||
|
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||||
|
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||||
|
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||||
|
13B07FB71A68108700A75B9A /* main.m */,
|
||||||
|
);
|
||||||
|
name = 2048;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
834D32361A76971A00F38302 /* ReactKit.xcodeproj */,
|
||||||
|
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
|
||||||
|
);
|
||||||
|
name = Libraries;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
832341B11AAA6A8300B99B32 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
832341B51AAA6A8300B99B32 /* libRCTText.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
832348241A77B50100B55238 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
832348291A77B50100B55238 /* libReactKit.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
83CBB9F61A601CBA00E9B192 = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
13B07FAE1A68108700A75B9A /* 2048 */,
|
||||||
|
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||||
|
83CBBA001A601CBA00E9B192 /* Products */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
83CBBA001A601CBA00E9B192 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
13B07F961A680F5B00A75B9A /* 2048.app */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
13B07F861A680F5B00A75B9A /* 2048 */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "2048" */;
|
||||||
|
buildPhases = (
|
||||||
|
13B07F871A680F5B00A75B9A /* Sources */,
|
||||||
|
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||||
|
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = 2048;
|
||||||
|
productName = "Hello World";
|
||||||
|
productReference = 13B07F961A680F5B00A75B9A /* 2048.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastUpgradeCheck = 0610;
|
||||||
|
ORGANIZATIONNAME = Facebook;
|
||||||
|
};
|
||||||
|
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "2048" */;
|
||||||
|
compatibilityVersion = "Xcode 3.2";
|
||||||
|
developmentRegion = English;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||||
|
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectReferences = (
|
||||||
|
{
|
||||||
|
ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
|
||||||
|
ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = 832348241A77B50100B55238 /* Products */;
|
||||||
|
ProjectRef = 834D32361A76971A00F38302 /* ReactKit.xcodeproj */;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
13B07F861A680F5B00A75B9A /* 2048 */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXReferenceProxy section */
|
||||||
|
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libRCTText.a;
|
||||||
|
remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
|
832348291A77B50100B55238 /* libReactKit.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libReactKit.a;
|
||||||
|
remoteRef = 832348281A77B50100B55238 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
|
/* End PBXReferenceProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||||
|
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||||
|
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXVariantGroup section */
|
||||||
|
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
13B07FB21A68108700A75B9A /* Base */,
|
||||||
|
);
|
||||||
|
name = LaunchScreen.xib;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
|
OTHER_LDFLAGS = "-ObjC";
|
||||||
|
PRODUCT_NAME = 2048;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
|
OTHER_LDFLAGS = "-ObjC";
|
||||||
|
PRODUCT_NAME = 2048;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
83CBBA201A601CBA00E9B192 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
|
"$(SRCROOT)/../../ReactKit/**",
|
||||||
|
);
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
83CBBA211A601CBA00E9B192 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
|
COPY_PHASE_STRIP = YES;
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
|
"$(SRCROOT)/../../ReactKit/**",
|
||||||
|
);
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "2048" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
13B07F941A680F5B00A75B9A /* Debug */,
|
||||||
|
13B07F951A680F5B00A75B9A /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "2048" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
83CBBA201A601CBA00E9B192 /* Debug */,
|
||||||
|
83CBBA211A601CBA00E9B192 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIWindow *window;
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
|
#import "RCTRootView.h"
|
||||||
|
|
||||||
|
@implementation AppDelegate
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||||
|
{
|
||||||
|
NSURL *jsCodeLocation;
|
||||||
|
RCTRootView *rootView = [[RCTRootView alloc] init];
|
||||||
|
|
||||||
|
// Loading JavaScript code - uncomment the one you want.
|
||||||
|
|
||||||
|
// OPTION 1
|
||||||
|
// Load from development server. Start the server from the repository root:
|
||||||
|
//
|
||||||
|
// $ npm start
|
||||||
|
//
|
||||||
|
// To run on device, change `localhost` to the IP address of your computer, and make sure your computer and
|
||||||
|
// iOS device are on the same Wi-Fi network.
|
||||||
|
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/2048/Game2048.includeRequire.runModule.bundle"];
|
||||||
|
|
||||||
|
// OPTION 2
|
||||||
|
// Load from pre-bundled file on disk. To re-generate the static bundle, run
|
||||||
|
//
|
||||||
|
// $ curl http://localhost:8081/Examples/2048/Game2048.includeRequire.runModule.bundle -o main.jsbundle
|
||||||
|
//
|
||||||
|
// and uncomment the next following line
|
||||||
|
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||||
|
|
||||||
|
rootView.scriptURL = jsCodeLocation;
|
||||||
|
rootView.moduleName = @"Game2048";
|
||||||
|
|
||||||
|
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||||
|
UIViewController *rootViewController = [[UIViewController alloc] init];
|
||||||
|
rootViewController.view = rootView;
|
||||||
|
self.window.rootViewController = rootViewController;
|
||||||
|
[self.window makeKeyAndVisible];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6254" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||||
|
<dependencies>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
||||||
|
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||||
|
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Facebook. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||||
|
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2048" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||||
|
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||||
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||||
|
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||||
|
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||||
|
</constraints>
|
||||||
|
<nil key="simulatedStatusBarMetrics"/>
|
||||||
|
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||||
|
<point key="canvasLocation" x="548" y="455"/>
|
||||||
|
</view>
|
||||||
|
</objects>
|
||||||
|
</document>
|
|
@ -0,0 +1,298 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* @providesModule Game2048
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var React = require('react-native');
|
||||||
|
var {
|
||||||
|
Animation,
|
||||||
|
AppRegistry,
|
||||||
|
StyleSheet,
|
||||||
|
Text,
|
||||||
|
View,
|
||||||
|
} = React;
|
||||||
|
|
||||||
|
var GameBoard = require('./GameBoard');
|
||||||
|
var TouchableBounce = require('TouchableBounce');
|
||||||
|
|
||||||
|
var BOARD_PADDING = 3;
|
||||||
|
var CELL_MARGIN = 4;
|
||||||
|
var CELL_SIZE = 60;
|
||||||
|
|
||||||
|
var Cell = React.createClass({
|
||||||
|
render: function() {
|
||||||
|
return <View style={styles.cell} />;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var Board = React.createClass({
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<View style={styles.board}>
|
||||||
|
<View style={styles.row}><Cell/><Cell/><Cell/><Cell/></View>
|
||||||
|
<View style={styles.row}><Cell/><Cell/><Cell/><Cell/></View>
|
||||||
|
<View style={styles.row}><Cell/><Cell/><Cell/><Cell/></View>
|
||||||
|
<View style={styles.row}><Cell/><Cell/><Cell/><Cell/></View>
|
||||||
|
{this.props.children}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var Tile = React.createClass({
|
||||||
|
mixins: [Animation.Mixin],
|
||||||
|
|
||||||
|
calculateOffset() {
|
||||||
|
var tile = this.props.tile;
|
||||||
|
|
||||||
|
var pos = (i) => {
|
||||||
|
return BOARD_PADDING + (i * (CELL_SIZE + CELL_MARGIN * 2) + CELL_MARGIN);
|
||||||
|
};
|
||||||
|
|
||||||
|
var animationPosition = (i) => {
|
||||||
|
return pos(i) + (CELL_SIZE / 2);
|
||||||
|
};
|
||||||
|
|
||||||
|
var offset = {
|
||||||
|
top: pos(tile.toRow()),
|
||||||
|
left: pos(tile.toColumn()),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (tile.isNew()) {
|
||||||
|
offset.opacity = 0;
|
||||||
|
} else {
|
||||||
|
var point = [
|
||||||
|
animationPosition(tile.toColumn()),
|
||||||
|
animationPosition(tile.toRow()),
|
||||||
|
];
|
||||||
|
this.startAnimation('this', 100, 0, 'easeInOutQuad', {position: point});
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.startAnimation('this', 300, 0, 'easeInOutQuad', {scaleXY: [1, 1]});
|
||||||
|
this.startAnimation('this', 100, 0, 'easeInOutQuad', {opacity: 1});
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
var tile = this.props.tile;
|
||||||
|
|
||||||
|
var tileStyles = [
|
||||||
|
styles.tile,
|
||||||
|
styles['tile' + tile.value],
|
||||||
|
this.calculateOffset()
|
||||||
|
];
|
||||||
|
|
||||||
|
var textStyles = [
|
||||||
|
styles.value,
|
||||||
|
tile.value > 4 && styles.whiteText,
|
||||||
|
tile.value > 100 && styles.threeDigits,
|
||||||
|
tile.value > 1000 && styles.fourDigits,
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View ref="this" style={tileStyles}>
|
||||||
|
<Text style={textStyles}>{tile.value}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var GameEndOverlay = React.createClass({
|
||||||
|
render() {
|
||||||
|
var board = this.props.board;
|
||||||
|
|
||||||
|
if (!board.hasWon() && !board.hasLost()) {
|
||||||
|
return <View/>;
|
||||||
|
}
|
||||||
|
|
||||||
|
var message = board.hasWon() ?
|
||||||
|
'Good Job!' : 'Game Over';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.overlay}>
|
||||||
|
<Text style={styles.overlayMessage}>{message}</Text>
|
||||||
|
<TouchableBounce onPress={this.props.onRestart}>
|
||||||
|
<View style={styles.tryAgain}>
|
||||||
|
<Text style={styles.tryAgainText}>Try Again?</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableBounce>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var Game2048 = React.createClass({
|
||||||
|
getInitialState() {
|
||||||
|
return { board: new GameBoard() };
|
||||||
|
},
|
||||||
|
|
||||||
|
restartGame() {
|
||||||
|
this.setState(this.getInitialState());
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTouchStart(event) {
|
||||||
|
if (this.state.board.hasWon()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.startX = event.nativeEvent.pageX;
|
||||||
|
this.startY = event.nativeEvent.pageY;
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTouchEnd(event) {
|
||||||
|
if (this.state.board.hasWon()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var deltaX = event.nativeEvent.pageX - this.startX;
|
||||||
|
var deltaY = event.nativeEvent.pageY - this.startY;
|
||||||
|
|
||||||
|
var direction = -1;
|
||||||
|
if (Math.abs(deltaX) > 3 * Math.abs(deltaY) && Math.abs(deltaX) > 30) {
|
||||||
|
direction = deltaX > 0 ? 2 : 0;
|
||||||
|
} else if (Math.abs(deltaY) > 3 * Math.abs(deltaX) && Math.abs(deltaY) > 30) {
|
||||||
|
direction = deltaY > 0 ? 3 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction !== -1) {
|
||||||
|
this.setState({board: this.state.board.move(direction)});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
var tiles = this.state.board.tiles
|
||||||
|
.filter((tile) => tile.value)
|
||||||
|
.map((tile) => <Tile ref={tile.id} key={tile.id} tile={tile} />);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={styles.container}
|
||||||
|
onTouchStart={this.handleTouchStart}
|
||||||
|
onTouchEnd={this.handleTouchEnd}>
|
||||||
|
<Board>
|
||||||
|
{tiles}
|
||||||
|
</Board>
|
||||||
|
<GameEndOverlay board={this.state.board} onRestart={this.restartGame} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
board: {
|
||||||
|
padding: BOARD_PADDING,
|
||||||
|
backgroundColor: '#bbaaaa',
|
||||||
|
borderRadius: 5,
|
||||||
|
},
|
||||||
|
overlay: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
backgroundColor: 'rgba(221, 221, 221, 0.5)',
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
overlayMessage: {
|
||||||
|
fontSize: 40,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
tryAgain: {
|
||||||
|
backgroundColor: '#887766',
|
||||||
|
padding: 20,
|
||||||
|
borderRadius: 5,
|
||||||
|
},
|
||||||
|
tryAgainText: {
|
||||||
|
color: '#ffffff',
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
cell: {
|
||||||
|
width: CELL_SIZE,
|
||||||
|
height: CELL_SIZE,
|
||||||
|
borderRadius: 5,
|
||||||
|
backgroundColor: '#ddccbb',
|
||||||
|
margin: CELL_MARGIN,
|
||||||
|
},
|
||||||
|
row: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
},
|
||||||
|
tile: {
|
||||||
|
position: 'absolute',
|
||||||
|
width: CELL_SIZE,
|
||||||
|
height: CELL_SIZE,
|
||||||
|
backgroundColor: '#ddccbb',
|
||||||
|
borderRadius: 5,
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
fontSize: 24,
|
||||||
|
color: '#776666',
|
||||||
|
fontFamily: 'Verdana',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
tile2: {
|
||||||
|
backgroundColor: '#eeeeee',
|
||||||
|
},
|
||||||
|
tile4: {
|
||||||
|
backgroundColor: '#eeeecc',
|
||||||
|
},
|
||||||
|
tile8: {
|
||||||
|
backgroundColor: '#ffbb88',
|
||||||
|
},
|
||||||
|
tile16: {
|
||||||
|
backgroundColor: '#ff9966',
|
||||||
|
},
|
||||||
|
tile32: {
|
||||||
|
backgroundColor: '#ff7755',
|
||||||
|
},
|
||||||
|
tile64: {
|
||||||
|
backgroundColor: '#ff5533',
|
||||||
|
},
|
||||||
|
tile128: {
|
||||||
|
backgroundColor: '#eecc77',
|
||||||
|
},
|
||||||
|
tile256: {
|
||||||
|
backgroundColor: '#eecc66',
|
||||||
|
},
|
||||||
|
tile512: {
|
||||||
|
backgroundColor: '#eecc55',
|
||||||
|
},
|
||||||
|
tile1024: {
|
||||||
|
backgroundColor: '#eecc33',
|
||||||
|
},
|
||||||
|
tile2048: {
|
||||||
|
backgroundColor: '#eecc22',
|
||||||
|
},
|
||||||
|
whiteText: {
|
||||||
|
color: '#ffffff',
|
||||||
|
},
|
||||||
|
threeDigits: {
|
||||||
|
fontSize: 20,
|
||||||
|
},
|
||||||
|
fourDigits: {
|
||||||
|
fontSize: 18,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
AppRegistry.registerComponent('Game2048', () => Game2048);
|
||||||
|
|
||||||
|
module.exports = Game2048;
|
|
@ -0,0 +1,189 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* @providesModule GameBoard
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// NB: Taken straight from: https://github.com/IvanVergiliev/2048-react/blob/master/src/board.js
|
||||||
|
// with no modificiation except to format it for CommonJS and fix lint errors
|
||||||
|
|
||||||
|
var rotateLeft = function (matrix) {
|
||||||
|
var rows = matrix.length;
|
||||||
|
var columns = matrix[0].length;
|
||||||
|
var res = [];
|
||||||
|
for (var row = 0; row < rows; ++row) {
|
||||||
|
res.push([]);
|
||||||
|
for (var column = 0; column < columns; ++column) {
|
||||||
|
res[row][column] = matrix[column][columns - row - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Tile = function (value, row, column) {
|
||||||
|
this.value = value || 0;
|
||||||
|
this.row = row || -1;
|
||||||
|
this.column = column || -1;
|
||||||
|
this.oldRow = -1;
|
||||||
|
this.oldColumn = -1;
|
||||||
|
this.markForDeletion = false;
|
||||||
|
this.mergedInto = null;
|
||||||
|
this.id = Tile.id++;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tile.id = 0;
|
||||||
|
|
||||||
|
Tile.prototype.moveTo = function (row, column) {
|
||||||
|
this.oldRow = this.row;
|
||||||
|
this.oldColumn = this.column;
|
||||||
|
this.row = row;
|
||||||
|
this.column = column;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tile.prototype.isNew = function () {
|
||||||
|
return this.oldRow === -1 && !this.mergedInto;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tile.prototype.hasMoved = function () {
|
||||||
|
return (this.fromRow() !== -1 && (this.fromRow() !== this.toRow() || this.fromColumn() !== this.toColumn())) ||
|
||||||
|
this.mergedInto;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tile.prototype.fromRow = function () {
|
||||||
|
return this.mergedInto ? this.row : this.oldRow;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tile.prototype.fromColumn = function () {
|
||||||
|
return this.mergedInto ? this.column : this.oldColumn;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tile.prototype.toRow = function () {
|
||||||
|
return this.mergedInto ? this.mergedInto.row : this.row;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tile.prototype.toColumn = function () {
|
||||||
|
return this.mergedInto ? this.mergedInto.column : this.column;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Board = function () {
|
||||||
|
this.tiles = [];
|
||||||
|
this.cells = [];
|
||||||
|
for (var i = 0; i < Board.size; ++i) {
|
||||||
|
this.cells[i] = [this.addTile(), this.addTile(), this.addTile(), this.addTile()];
|
||||||
|
}
|
||||||
|
this.addRandomTile();
|
||||||
|
this.setPositions();
|
||||||
|
this.won = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Board.prototype.addTile = function () {
|
||||||
|
var res = new Tile();
|
||||||
|
Tile.apply(res, arguments);
|
||||||
|
this.tiles.push(res);
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
Board.size = 4;
|
||||||
|
|
||||||
|
Board.prototype.moveLeft = function () {
|
||||||
|
var hasChanged = false;
|
||||||
|
for (var row = 0; row < Board.size; ++row) {
|
||||||
|
var currentRow = this.cells[row].filter(function (tile) { return tile.value !== 0; });
|
||||||
|
var resultRow = [];
|
||||||
|
for (var target = 0; target < Board.size; ++target) {
|
||||||
|
var targetTile = currentRow.length ? currentRow.shift() : this.addTile();
|
||||||
|
if (currentRow.length > 0 && currentRow[0].value === targetTile.value) {
|
||||||
|
var tile1 = targetTile;
|
||||||
|
targetTile = this.addTile(targetTile.value);
|
||||||
|
tile1.mergedInto = targetTile;
|
||||||
|
var tile2 = currentRow.shift();
|
||||||
|
tile2.mergedInto = targetTile;
|
||||||
|
targetTile.value += tile2.value;
|
||||||
|
}
|
||||||
|
resultRow[target] = targetTile;
|
||||||
|
this.won |= (targetTile.value === 2048);
|
||||||
|
hasChanged |= (targetTile.value !== this.cells[row][target].value);
|
||||||
|
}
|
||||||
|
this.cells[row] = resultRow;
|
||||||
|
}
|
||||||
|
return hasChanged;
|
||||||
|
};
|
||||||
|
|
||||||
|
Board.prototype.setPositions = function () {
|
||||||
|
this.cells.forEach(function (row, rowIndex) {
|
||||||
|
row.forEach(function (tile, columnIndex) {
|
||||||
|
tile.oldRow = tile.row;
|
||||||
|
tile.oldColumn = tile.column;
|
||||||
|
tile.row = rowIndex;
|
||||||
|
tile.column = columnIndex;
|
||||||
|
tile.markForDeletion = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Board.fourProbability = 0.1;
|
||||||
|
|
||||||
|
Board.prototype.addRandomTile = function () {
|
||||||
|
var emptyCells = [];
|
||||||
|
for (var r = 0; r < Board.size; ++r) {
|
||||||
|
for (var c = 0; c < Board.size; ++c) {
|
||||||
|
if (this.cells[r][c].value === 0) {
|
||||||
|
emptyCells.push({r: r, c: c});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var index = Math.floor(Math.random() * emptyCells.length);
|
||||||
|
var cell = emptyCells[index];
|
||||||
|
var newValue = Math.random() < Board.fourProbability ? 4 : 2;
|
||||||
|
this.cells[cell.r][cell.c] = this.addTile(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
Board.prototype.move = function (direction) {
|
||||||
|
// 0 -> left, 1 -> up, 2 -> right, 3 -> down
|
||||||
|
this.clearOldTiles();
|
||||||
|
for (var i = 0; i < direction; ++i) {
|
||||||
|
this.cells = rotateLeft(this.cells);
|
||||||
|
}
|
||||||
|
var hasChanged = this.moveLeft();
|
||||||
|
for (var i = direction; i < 4; ++i) {
|
||||||
|
this.cells = rotateLeft(this.cells);
|
||||||
|
}
|
||||||
|
if (hasChanged) {
|
||||||
|
this.addRandomTile();
|
||||||
|
}
|
||||||
|
this.setPositions();
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Board.prototype.clearOldTiles = function () {
|
||||||
|
this.tiles = this.tiles.filter(function (tile) { return tile.markForDeletion === false; });
|
||||||
|
this.tiles.forEach(function (tile) { tile.markForDeletion = true; });
|
||||||
|
};
|
||||||
|
|
||||||
|
Board.prototype.hasWon = function () {
|
||||||
|
return this.won;
|
||||||
|
};
|
||||||
|
|
||||||
|
Board.deltaX = [-1, 0, 1, 0];
|
||||||
|
Board.deltaY = [0, -1, 0, 1];
|
||||||
|
|
||||||
|
Board.prototype.hasLost = function () {
|
||||||
|
var canMove = false;
|
||||||
|
for (var row = 0; row < Board.size; ++row) {
|
||||||
|
for (var column = 0; column < Board.size; ++column) {
|
||||||
|
canMove |= (this.cells[row][column].value === 0);
|
||||||
|
for (var dir = 0; dir < 4; ++dir) {
|
||||||
|
var newRow = row + Board.deltaX[dir];
|
||||||
|
var newColumn = column + Board.deltaY[dir];
|
||||||
|
if (newRow < 0 || newRow >= Board.size || newColumn < 0 || newColumn >= Board.size) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
canMove |= (this.cells[row][column].value === this.cells[newRow][newColumn].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !canMove;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Board;
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"size" : "29x29",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"size" : "29x29",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"size" : "40x40",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"size" : "40x40",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"size" : "60x60",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"size" : "60x60",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.facebook.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
<key>UIRequiredDeviceCapabilities</key>
|
||||||
|
<array>
|
||||||
|
<string>armv7</string>
|
||||||
|
</array>
|
||||||
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
|
int main(int argc, char * argv[]) {
|
||||||
|
@autoreleasepool {
|
||||||
|
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* @providesModule Animation
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var { RCTAnimationManager } = require('NativeModules');
|
||||||
|
var AnimationUtils = require('AnimationUtils');
|
||||||
|
|
||||||
|
type EasingFunction = (t: number) => number;
|
||||||
|
|
||||||
|
var Animation = {
|
||||||
|
Mixin: require('AnimationMixin'),
|
||||||
|
|
||||||
|
startAnimation: function(
|
||||||
|
node: any,
|
||||||
|
duration: number,
|
||||||
|
delay: number,
|
||||||
|
easing: (string | EasingFunction),
|
||||||
|
properties: {[key: string]: any}
|
||||||
|
): number {
|
||||||
|
var nodeHandle = +node.getNodeHandle();
|
||||||
|
var easingSample = AnimationUtils.evaluateEasingFunction(duration, easing);
|
||||||
|
RCTAnimationManager.startAnimation(nodeHandle, AnimationUtils.allocateTag(), duration, delay, easingSample, properties);
|
||||||
|
},
|
||||||
|
|
||||||
|
stopAnimation: function(tag) {
|
||||||
|
RCTAnimationManager.stopAnimation(tag);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Animation;
|
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* @providesModule AnimationMixin
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var AnimationUtils = require('AnimationUtils');
|
||||||
|
var { RCTAnimationManager } = require('NativeModules');
|
||||||
|
|
||||||
|
var invariant = require('invariant');
|
||||||
|
|
||||||
|
type EasingFunction = (t: number) => number;
|
||||||
|
|
||||||
|
var AnimationMixin = {
|
||||||
|
getInitialState: function(): Object {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
|
||||||
|
startAnimation: function(
|
||||||
|
refKey: string,
|
||||||
|
duration: number,
|
||||||
|
delay: number,
|
||||||
|
easing: (string | EasingFunction),
|
||||||
|
properties: {[key: string]: any}
|
||||||
|
): number {
|
||||||
|
var ref = this.refs[refKey];
|
||||||
|
invariant(
|
||||||
|
ref,
|
||||||
|
'Invalid refKey ' + refKey + '; ' +
|
||||||
|
'valid refs: ' + JSON.stringify(Object.keys(this.refs))
|
||||||
|
);
|
||||||
|
|
||||||
|
var nodeHandle = +ref.getNodeHandle();
|
||||||
|
var easingSample = AnimationUtils.evaluateEasingFunction(duration, easing);
|
||||||
|
RCTAnimationManager.startAnimation(nodeHandle, AnimationUtils.allocateTag(), duration, delay, easingSample, properties);
|
||||||
|
},
|
||||||
|
|
||||||
|
stopAnimation: function(tag: number) {
|
||||||
|
RCTAnimationManager.stopAnimation(tag);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = AnimationMixin;
|
|
@ -0,0 +1,226 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* @providesModule AnimationUtils
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
type EasingFunction = (t: number) => number;
|
||||||
|
|
||||||
|
var b = 0,
|
||||||
|
c = 1,
|
||||||
|
d = 1;
|
||||||
|
var defaults = {
|
||||||
|
easeInQuad: function(t) {
|
||||||
|
return c * (t /= 1) * t + b;
|
||||||
|
},
|
||||||
|
easeOutQuad: function(t) {
|
||||||
|
return -c * (t /= d) * (t - 2) + b;
|
||||||
|
},
|
||||||
|
easeInOutQuad: function(t) {
|
||||||
|
if ((t /= d / 2) < 1) {
|
||||||
|
return c / 2 * t * t + b;
|
||||||
|
}
|
||||||
|
return -c / 2 * ((--t) * (t - 2) - 1) + b;
|
||||||
|
},
|
||||||
|
easeInCubic: function(t) {
|
||||||
|
return c * (t /= d) * t * t + b;
|
||||||
|
},
|
||||||
|
easeOutCubic: function(t) {
|
||||||
|
return c * ((t = t / d - 1) * t * t + 1) + b;
|
||||||
|
},
|
||||||
|
easeInOutCubic: function(t) {
|
||||||
|
if ((t /= d / 2) < 1) {
|
||||||
|
return c / 2 * t * t * t + b;
|
||||||
|
}
|
||||||
|
return c / 2 * ((t -= 2) * t * t + 2) + b;
|
||||||
|
},
|
||||||
|
easeInQuart: function(t) {
|
||||||
|
return c * (t /= d) * t * t * t + b;
|
||||||
|
},
|
||||||
|
easeOutQuart: function(t) {
|
||||||
|
return -c * ((t = t / d - 1) * t * t * t - 1) + b;
|
||||||
|
},
|
||||||
|
easeInOutQuart: function(t) {
|
||||||
|
if ((t /= d / 2) < 1) {
|
||||||
|
return c / 2 * t * t * t * t + b;
|
||||||
|
}
|
||||||
|
return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
|
||||||
|
},
|
||||||
|
easeInQuint: function(t) {
|
||||||
|
return c * (t /= d) * t * t * t * t + b;
|
||||||
|
},
|
||||||
|
easeOutQuint: function(t) {
|
||||||
|
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
|
||||||
|
},
|
||||||
|
easeInOutQuint: function(t) {
|
||||||
|
if ((t /= d / 2) < 1) {
|
||||||
|
return c / 2 * t * t * t * t * t + b;
|
||||||
|
}
|
||||||
|
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
|
||||||
|
},
|
||||||
|
easeInSine: function(t) {
|
||||||
|
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
|
||||||
|
},
|
||||||
|
easeOutSine: function(t) {
|
||||||
|
return c * Math.sin(t / d * (Math.PI / 2)) + b;
|
||||||
|
},
|
||||||
|
easeInOutSine: function(t) {
|
||||||
|
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
|
||||||
|
},
|
||||||
|
easeInExpo: function(t) {
|
||||||
|
return (t === 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
|
||||||
|
},
|
||||||
|
easeOutExpo: function(t) {
|
||||||
|
return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
|
||||||
|
},
|
||||||
|
easeInOutExpo: function(t) {
|
||||||
|
if (t === 0) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
if (t === d) {
|
||||||
|
return b + c;
|
||||||
|
}
|
||||||
|
if ((t /= d / 2) < 1) {
|
||||||
|
return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
|
||||||
|
}
|
||||||
|
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
|
||||||
|
},
|
||||||
|
easeInCirc: function(t) {
|
||||||
|
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
|
||||||
|
},
|
||||||
|
easeOutCirc: function(t) {
|
||||||
|
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
|
||||||
|
},
|
||||||
|
easeInOutCirc: function(t) {
|
||||||
|
if ((t /= d / 2) < 1) {
|
||||||
|
return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
|
||||||
|
}
|
||||||
|
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
|
||||||
|
},
|
||||||
|
easeInElastic: function(t) {
|
||||||
|
var s = 1.70158;
|
||||||
|
var p = 0;
|
||||||
|
var a = c;
|
||||||
|
if (t === 0) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
if ((t /= d) === 1) {
|
||||||
|
return b + c;
|
||||||
|
}
|
||||||
|
if (!p) {
|
||||||
|
p = d * 0.3;
|
||||||
|
}
|
||||||
|
if (a < Math.abs(c)) {
|
||||||
|
a = c;
|
||||||
|
var s = p / 4;
|
||||||
|
} else {
|
||||||
|
var s = p / (2 * Math.PI) * Math.asin(c / a);
|
||||||
|
}
|
||||||
|
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
|
||||||
|
},
|
||||||
|
easeOutElastic: function(t) {
|
||||||
|
var s = 1.70158;
|
||||||
|
var p = 0;
|
||||||
|
var a = c;
|
||||||
|
if (t === 0) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
if ((t /= d) === 1) {
|
||||||
|
return b + c;
|
||||||
|
}
|
||||||
|
if (!p) {
|
||||||
|
p = d * 0.3;
|
||||||
|
}
|
||||||
|
if (a < Math.abs(c)) {
|
||||||
|
a = c;
|
||||||
|
var s = p / 4;
|
||||||
|
} else {
|
||||||
|
var s = p / (2 * Math.PI) * Math.asin(c / a);
|
||||||
|
}
|
||||||
|
return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
|
||||||
|
},
|
||||||
|
easeInOutElastic: function(t) {
|
||||||
|
var s = 1.70158;
|
||||||
|
var p = 0;
|
||||||
|
var a = c;
|
||||||
|
if (t === 0) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
if ((t /= d / 2) === 2) {
|
||||||
|
return b + c;
|
||||||
|
}
|
||||||
|
if (!p) {
|
||||||
|
p = d * (0.3 * 1.5);
|
||||||
|
}
|
||||||
|
if (a < Math.abs(c)) {
|
||||||
|
a = c;
|
||||||
|
var s = p / 4;
|
||||||
|
} else {
|
||||||
|
var s = p / (2 * Math.PI) * Math.asin(c / a);
|
||||||
|
}
|
||||||
|
if (t < 1) {
|
||||||
|
return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
|
||||||
|
}
|
||||||
|
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * 0.5 + c + b;
|
||||||
|
},
|
||||||
|
easeInBack: function(t) {
|
||||||
|
var s = 1.70158;
|
||||||
|
return c * (t /= d) * t * ((s + 1) * t - s) + b;
|
||||||
|
},
|
||||||
|
easeOutBack: function(t) {
|
||||||
|
var s = 1.70158;
|
||||||
|
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
|
||||||
|
},
|
||||||
|
easeInOutBack: function(t) {
|
||||||
|
var s = 1.70158;
|
||||||
|
if ((t /= d / 2) < 1) {
|
||||||
|
return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
|
||||||
|
}
|
||||||
|
return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
|
||||||
|
},
|
||||||
|
easeInBounce: function(t) {
|
||||||
|
return c - this.easeOutBounce(d - t) + b;
|
||||||
|
},
|
||||||
|
easeOutBounce: function(t) {
|
||||||
|
if ((t /= d) < (1 / 2.75)) {
|
||||||
|
return c * (7.5625 * t * t) + b;
|
||||||
|
} else if (t < (2 / 2.75)) {
|
||||||
|
return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;
|
||||||
|
} else if (t < (2.5 / 2.75)) {
|
||||||
|
return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;
|
||||||
|
} else {
|
||||||
|
return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
easeInOutBounce: function(t) {
|
||||||
|
if (t < d / 2) {
|
||||||
|
return this.easeInBounce(t * 2) * 0.5 + b;
|
||||||
|
}
|
||||||
|
return this.easeOutBounce(t * 2 - d) * 0.5 + c * 0.5 + b;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var ticksPerSecond = 60;
|
||||||
|
var lastUsedTag = 0;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
allocateTag: function(): number {
|
||||||
|
return ++lastUsedTag;
|
||||||
|
},
|
||||||
|
|
||||||
|
evaluateEasingFunction: function(duration: number, easing: string | EasingFunction): Array<number> {
|
||||||
|
if (typeof easing === 'string') {
|
||||||
|
easing = defaults[easing] || defaults.easeOutQuad;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tickCount = Math.round(duration * ticksPerSecond / 1000);
|
||||||
|
var sample = [];
|
||||||
|
for (var i = 0; i <= tickCount; i++) {
|
||||||
|
sample.push(easing(i / tickCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sample;
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,124 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* @providesModule TouchableBounce
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var NativeMethodsMixin = require('NativeMethodsMixin');
|
||||||
|
var React = require('React');
|
||||||
|
var POPAnimation = require('POPAnimation');
|
||||||
|
var Animation = require('Animation');
|
||||||
|
var Touchable = require('Touchable');
|
||||||
|
|
||||||
|
var merge = require('merge');
|
||||||
|
var copyProperties = require('copyProperties');
|
||||||
|
var onlyChild = require('onlyChild');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the scroll view is disabled, this defines how far your touch may move
|
||||||
|
* off of the button, before deactivating the button. Once deactivated, try
|
||||||
|
* moving it back and you'll see that the button is once again reactivated!
|
||||||
|
* Move it back and forth several times while the scroll view is disabled.
|
||||||
|
*/
|
||||||
|
var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
|
||||||
|
/**
|
||||||
|
* Example of using the `TouchableMixin` to play well with other responder
|
||||||
|
* locking views including `ScrollView`. `TouchableMixin` provides touchable
|
||||||
|
* hooks (`this.touchableHandle*`) that we forward events to. In turn,
|
||||||
|
* `TouchableMixin` expects us to implement some abstract methods to handle
|
||||||
|
* interesting interactions such as `handleTouchablePress`.
|
||||||
|
*/
|
||||||
|
var TouchableBounce = React.createClass({
|
||||||
|
mixins: [Touchable.Mixin, NativeMethodsMixin],
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
onPress: React.PropTypes.func,
|
||||||
|
// The function passed takes a callback to start the animation which should
|
||||||
|
// be run after this onPress handler is done. You can use this (for example)
|
||||||
|
// to update UI before starting the animation.
|
||||||
|
onPressWithCompletion: React.PropTypes.func,
|
||||||
|
// the function passed is called after the animation is complete
|
||||||
|
onPressAnimationComplete: React.PropTypes.func,
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialState: function() {
|
||||||
|
return merge(this.touchableGetInitialState(), {animationID: null});
|
||||||
|
},
|
||||||
|
|
||||||
|
bounceTo: function(value, velocity, bounciness, fromValue, callback) {
|
||||||
|
if (POPAnimation) {
|
||||||
|
this.state.animationID && this.removeAnimation(this.state.animationID);
|
||||||
|
var anim = {
|
||||||
|
property: POPAnimation.Properties.scaleXY,
|
||||||
|
dynamicsTension: 0,
|
||||||
|
toValue: [value, value],
|
||||||
|
velocity: [velocity, velocity],
|
||||||
|
springBounciness: bounciness,
|
||||||
|
};
|
||||||
|
if (fromValue) {
|
||||||
|
anim.fromValue = [fromValue, fromValue];
|
||||||
|
}
|
||||||
|
this.state.animationID = POPAnimation.createSpringAnimation(anim);
|
||||||
|
this.addAnimation(this.state.animationID, callback);
|
||||||
|
} else {
|
||||||
|
Animation.startAnimation(this, 300, 0, 'easeOutBack', {scaleXY: [value, value]});
|
||||||
|
if (fromValue && typeof fromValue === 'function') {
|
||||||
|
callback = fromValue;
|
||||||
|
}
|
||||||
|
if (callback) {
|
||||||
|
setTimeout(callback, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `Touchable.Mixin` self callbacks. The mixin will invoke these if they are
|
||||||
|
* defined on your component.
|
||||||
|
*/
|
||||||
|
touchableHandleActivePressIn: function() {
|
||||||
|
this.bounceTo(0.93, 0.1, 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleActivePressOut: function() {
|
||||||
|
this.bounceTo(1, 0.4, 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandlePress: function() {
|
||||||
|
if (this.props.onPressWithCompletion) {
|
||||||
|
this.props.onPressWithCompletion(
|
||||||
|
this.bounceTo.bind(this, 1, 10, 10, 0.93, this.props.onPressAnimationComplete)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bounceTo(1, 10, 10, undefined, this.props.onPressAnimationComplete);
|
||||||
|
this.props.onPress && this.props.onPress();
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableGetPressRectOffset: function() {
|
||||||
|
return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant!
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableGetHighlightDelayMS: function() {
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
// Note(vjeux): use cloneWithProps once React has been upgraded
|
||||||
|
var child = onlyChild(this.props.children);
|
||||||
|
copyProperties(child.props, {
|
||||||
|
accessible: true,
|
||||||
|
testID: this.props.testID,
|
||||||
|
onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder,
|
||||||
|
onResponderTerminationRequest: this.touchableHandleResponderTerminationRequest,
|
||||||
|
onResponderGrant: this.touchableHandleResponderGrant,
|
||||||
|
onResponderMove: this.touchableHandleResponderMove,
|
||||||
|
onResponderRelease: this.touchableHandleResponderRelease,
|
||||||
|
onResponderTerminate: this.touchableHandleResponderTerminate
|
||||||
|
});
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = TouchableBounce;
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
var ReactNative = {
|
var ReactNative = {
|
||||||
...require('React'),
|
...require('React'),
|
||||||
|
Animation: require('Animation'),
|
||||||
AppRegistry: require('AppRegistry'),
|
AppRegistry: require('AppRegistry'),
|
||||||
CameraRoll: require('CameraRoll'),
|
CameraRoll: require('CameraRoll'),
|
||||||
DatePickerIOS: require('DatePickerIOS'),
|
DatePickerIOS: require('DatePickerIOS'),
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
#define RCTErrorDomain @"RCTErrorDomain"
|
#define RCTErrorDomain @"RCTErrorDomain"
|
||||||
|
|
||||||
#define RCTAssert(condition, message, ...) _RCTAssert(condition, message, ##__VA_ARGS__)
|
#define RCTAssert(condition, message, ...) _RCTAssert((condition) != 0, message, ##__VA_ARGS__)
|
||||||
#define RCTCAssert(condition, message, ...) _RCTCAssert(condition, message, ##__VA_ARGS__)
|
#define RCTCAssert(condition, message, ...) _RCTCAssert((condition) != 0, message, ##__VA_ARGS__)
|
||||||
|
|
||||||
typedef void (^RCTAssertFunction)(BOOL condition, NSString *message, ...);
|
typedef void (^RCTAssertFunction)(BOOL condition, NSString *message, ...);
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,12 @@ BOOL RCTSetProperty(id target, NSString *keypath, id json);
|
||||||
*/
|
*/
|
||||||
BOOL RCTCopyProperty(id target, id source, NSString *keypath);
|
BOOL RCTCopyProperty(id target, id source, NSString *keypath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function attempts to convert a JSON value to an object that can be used
|
||||||
|
* in KVC with the specific target and key path.
|
||||||
|
*/
|
||||||
|
id RCTConvertValue(id target, NSString *keypath, id json);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -608,7 +608,7 @@ static NSString *RCTGuessTypeEncoding(id target, NSString *key, id value, NSStri
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NSDictionary *RCTConvertValue(id value, NSString *encoding)
|
static id RCTConvertValueWithEncoding(id value, NSString *encoding)
|
||||||
{
|
{
|
||||||
static NSDictionary *converters = nil;
|
static NSDictionary *converters = nil;
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
|
@ -690,18 +690,7 @@ static NSDictionary *RCTConvertValue(id value, NSString *encoding)
|
||||||
return converter ? converter(value) : value;
|
return converter ? converter(value) : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL RCTSetProperty(id target, NSString *keypath, id value)
|
static NSString *RCTPropertyEncoding(id target, NSString *key, id value) {
|
||||||
{
|
|
||||||
// Split keypath
|
|
||||||
NSArray *parts = [keypath componentsSeparatedByString:@"."];
|
|
||||||
NSString *key = [parts lastObject];
|
|
||||||
for (NSUInteger i = 0; i < parts.count - 1; i++) {
|
|
||||||
target = [target valueForKey:parts[i]];
|
|
||||||
if (!target) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check target class for property definition
|
// Check target class for property definition
|
||||||
NSString *encoding = nil;
|
NSString *encoding = nil;
|
||||||
objc_property_t property = class_getProperty([target class], [key UTF8String]);
|
objc_property_t property = class_getProperty([target class], [key UTF8String]);
|
||||||
|
@ -720,7 +709,7 @@ BOOL RCTSetProperty(id target, NSString *keypath, id value)
|
||||||
[key substringFromIndex:1]]);
|
[key substringFromIndex:1]]);
|
||||||
|
|
||||||
if (![target respondsToSelector:setter]) {
|
if (![target respondsToSelector:setter]) {
|
||||||
return NO;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get type of first method argument
|
// Get type of first method argument
|
||||||
|
@ -730,17 +719,92 @@ BOOL RCTSetProperty(id target, NSString *keypath, id value)
|
||||||
encoding = @(typeEncoding);
|
encoding = @(typeEncoding);
|
||||||
free(typeEncoding);
|
free(typeEncoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (encoding.length == 0 || [encoding isEqualToString:@(@encode(id))]) {
|
||||||
|
// Not enough info about the type encoding to be useful, so
|
||||||
|
// try to guess the type from the value and property name
|
||||||
|
encoding = RCTGuessTypeEncoding(target, key, value, encoding);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encoding.length == 0 || [encoding isEqualToString:@(@encode(id))]) {
|
return encoding;
|
||||||
// Not enough info about the type encoding to be useful, so
|
}
|
||||||
// try to guess the type from the value and property name
|
|
||||||
encoding = RCTGuessTypeEncoding(target, key, value, encoding);
|
static id RCTConvertValueWithExplicitEncoding(id target, NSString *key, id json, NSString *encoding) {
|
||||||
|
if (!encoding) return nil;
|
||||||
|
|
||||||
|
// Special case for numeric encodings, which may be enums
|
||||||
|
if ([json isKindOfClass:[NSString class]] &&
|
||||||
|
[@"iIsSlLqQ" rangeOfString:[encoding substringToIndex:1]].length) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOTE: the property names below may seem weird, but it's
|
||||||
|
* because they are tested as case-sensitive suffixes, so
|
||||||
|
* "apitalizationType" will match any of the following
|
||||||
|
*
|
||||||
|
* - capitalizationType
|
||||||
|
* - autocapitalizationType
|
||||||
|
* - autoCapitalizationType
|
||||||
|
* - titleCapitalizationType
|
||||||
|
* - etc.
|
||||||
|
*/
|
||||||
|
static NSDictionary *converters = nil;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
converters =
|
||||||
|
@{
|
||||||
|
@"apitalizationType": ^(id val) {
|
||||||
|
return [RCTConvert UITextAutocapitalizationType:val];
|
||||||
|
},
|
||||||
|
@"eyboardType": ^(id val) {
|
||||||
|
return [RCTConvert UIKeyboardType:val];
|
||||||
|
},
|
||||||
|
@"extAlignment": ^(id val) {
|
||||||
|
return [RCTConvert NSTextAlignment:val];
|
||||||
|
},
|
||||||
|
@"ointerEvents": ^(id val) {
|
||||||
|
return [RCTConvert RCTPointerEvents:val];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
for (NSString *subkey in converters) {
|
||||||
|
if ([key hasSuffix:subkey]) {
|
||||||
|
NSInteger (^converter)(NSString *) = converters[subkey];
|
||||||
|
json = @(converter(json));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return RCTConvertValueWithEncoding(json, encoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
id RCTConvertValue(id target, NSString *key, id json) {
|
||||||
|
NSString *encoding = RCTPropertyEncoding(target, key, json);
|
||||||
|
return RCTConvertValueWithExplicitEncoding(target, key, json, encoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL RCTSetProperty(id target, NSString *keypath, id value)
|
||||||
|
{
|
||||||
|
// Split keypath
|
||||||
|
NSArray *parts = [keypath componentsSeparatedByString:@"."];
|
||||||
|
NSString *key = [parts lastObject];
|
||||||
|
for (NSUInteger i = 0; i < parts.count - 1; i++) {
|
||||||
|
target = [target valueForKey:parts[i]];
|
||||||
|
if (!target) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString *encoding = RCTPropertyEncoding(target, key, value);
|
||||||
|
if (!encoding) return NO;
|
||||||
|
|
||||||
|
value = RCTConvertValueWithExplicitEncoding(target, keypath, value, encoding);
|
||||||
|
|
||||||
// Special case for numeric encodings, which may be enums
|
// Special case for numeric encodings, which may be enums
|
||||||
if ([value isKindOfClass:[NSString class]] &&
|
if ([value isKindOfClass:[NSString class]] &&
|
||||||
[@"iIsSlLqQ" rangeOfString:[encoding substringToIndex:1]].length) {
|
[@"iIsSlLqQ" rangeOfString:[encoding substringToIndex:1]].location != NSNotFound) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOTE: the property names below may seem weird, but it's
|
* NOTE: the property names below may seem weird, but it's
|
||||||
|
@ -798,15 +862,15 @@ BOOL RCTSetProperty(id target, NSString *keypath, id value)
|
||||||
});
|
});
|
||||||
|
|
||||||
void (^block)(UITextField *f, NSInteger v) = specialCases[key];
|
void (^block)(UITextField *f, NSInteger v) = specialCases[key];
|
||||||
if (block)
|
if (block) {
|
||||||
{
|
|
||||||
block(target, [value integerValue]);
|
block(target, [value integerValue]);
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set converted value
|
// Set converted value
|
||||||
[target setValue:RCTConvertValue(value, encoding) forKey:key];
|
[target setValue:value forKey:key];
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "RCTBridgeModule.h"
|
||||||
|
|
||||||
|
@interface RCTAnimationManager : NSObject <RCTBridgeModule>
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,203 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import "RCTAnimationManager.h"
|
||||||
|
|
||||||
|
#import <Accelerate/Accelerate.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
#import "RCTSparseArray.h"
|
||||||
|
#import "RCTUIManager.h"
|
||||||
|
|
||||||
|
#if CGFLOAT_IS_DOUBLE
|
||||||
|
#define CG_APPEND(PREFIX, SUFFIX_F, SUFFIX_D) PREFIX##SUFFIX_D
|
||||||
|
#else
|
||||||
|
#define CG_APPEND(PREFIX, SUFFIX_F, SUFFIX_D) PREFIX##SUFFIX_F
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@implementation RCTAnimationManager
|
||||||
|
{
|
||||||
|
RCTSparseArray *_animationRegistry; // Main thread only; animation tag -> view tag
|
||||||
|
}
|
||||||
|
|
||||||
|
@synthesize bridge = _bridge;
|
||||||
|
|
||||||
|
- (instancetype)init
|
||||||
|
{
|
||||||
|
if ((self = [super init])) {
|
||||||
|
_animationRegistry = [[RCTSparseArray alloc] init];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id (^)(CGFloat))interpolateFrom:(CGFloat[])fromArray to:(CGFloat[])toArray count:(NSUInteger)count typeName:(const char *)typeName
|
||||||
|
{
|
||||||
|
if (count == 1) {
|
||||||
|
CGFloat from = *fromArray, to = *toArray, delta = to - from;
|
||||||
|
return ^(CGFloat t) {
|
||||||
|
return @(from + t * delta);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
CG_APPEND(vDSP_vsub,,D)(fromArray, 1, toArray, 1, toArray, 1, count);
|
||||||
|
|
||||||
|
const size_t size = count * sizeof(CGFloat);
|
||||||
|
NSData *deltaData = [NSData dataWithBytes:toArray length:size];
|
||||||
|
NSData *fromData = [NSData dataWithBytes:fromArray length:size];
|
||||||
|
|
||||||
|
return ^(CGFloat t) {
|
||||||
|
const CGFloat *delta = deltaData.bytes;
|
||||||
|
const CGFloat *fromArray = fromData.bytes;
|
||||||
|
|
||||||
|
CGFloat value[count];
|
||||||
|
CG_APPEND(vDSP_vma,,D)(delta, 1, &t, 0, fromArray, 1, value, 1, count);
|
||||||
|
return [NSValue valueWithBytes:value objCType:typeName];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)startAnimationForTag:(NSNumber *)reactTag animationTag:(NSNumber *)animationTag duration:(double)duration delay:(double)delay easingSample:(NSArray *)easingSample properties:(NSDictionary *)properties
|
||||||
|
{
|
||||||
|
RCT_EXPORT(startAnimation);
|
||||||
|
|
||||||
|
__weak RCTAnimationManager *weakSelf = self;
|
||||||
|
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
|
RCTAnimationManager *strongSelf = weakSelf;
|
||||||
|
|
||||||
|
UIView *view = viewRegistry[reactTag];
|
||||||
|
if (!view) {
|
||||||
|
RCTLogWarn(@"React tag %@ is not registered with the view registry", reactTag);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[properties enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
|
||||||
|
NSValue *toValue = nil;
|
||||||
|
if ([key isEqualToString:@"scaleXY"]) {
|
||||||
|
key = @"transform.scale";
|
||||||
|
toValue = obj[0];
|
||||||
|
} else if ([obj respondsToSelector:@selector(count)]) {
|
||||||
|
switch ([obj count]) {
|
||||||
|
case 2:
|
||||||
|
if ([obj respondsToSelector:@selector(objectForKey:)] && [obj objectForKey:@"w"]) {
|
||||||
|
toValue = [NSValue valueWithCGSize:[RCTConvert CGSize:obj]];
|
||||||
|
} else {
|
||||||
|
toValue = [NSValue valueWithCGPoint:[RCTConvert CGPoint:obj]];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
toValue = [NSValue valueWithCGRect:[RCTConvert CGRect:obj]];
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
toValue = [NSValue valueWithCGAffineTransform:[RCTConvert CGAffineTransform:obj]];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!toValue) toValue = obj;
|
||||||
|
|
||||||
|
const char *typeName = toValue.objCType;
|
||||||
|
|
||||||
|
size_t count;
|
||||||
|
switch (typeName[0]) {
|
||||||
|
case 'i':
|
||||||
|
case 'I':
|
||||||
|
case 's':
|
||||||
|
case 'S':
|
||||||
|
case 'l':
|
||||||
|
case 'L':
|
||||||
|
case 'q':
|
||||||
|
case 'Q':
|
||||||
|
count = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
NSUInteger size;
|
||||||
|
NSGetSizeAndAlignment(typeName, &size, NULL);
|
||||||
|
count = size / sizeof(CGFloat);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CGFloat toFields[count];
|
||||||
|
|
||||||
|
switch (typeName[0]) {
|
||||||
|
#define CASE(encoding, type) \
|
||||||
|
case encoding: { \
|
||||||
|
type value; \
|
||||||
|
[toValue getValue:&value]; \
|
||||||
|
toFields[0] = value; \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
CASE('i', int)
|
||||||
|
CASE('I', unsigned int)
|
||||||
|
CASE('s', short)
|
||||||
|
CASE('S', unsigned short)
|
||||||
|
CASE('l', long)
|
||||||
|
CASE('L', unsigned long)
|
||||||
|
CASE('q', long long)
|
||||||
|
CASE('Q', unsigned long long)
|
||||||
|
|
||||||
|
#undef CASE
|
||||||
|
|
||||||
|
default:
|
||||||
|
[toValue getValue:toFields];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSValue *fromValue = [view.layer.presentationLayer valueForKeyPath:key];
|
||||||
|
CGFloat fromFields[count];
|
||||||
|
[fromValue getValue:fromFields];
|
||||||
|
|
||||||
|
id (^interpolationBlock)(CGFloat t) = [strongSelf interpolateFrom:fromFields to:toFields count:count typeName:typeName];
|
||||||
|
|
||||||
|
NSMutableArray *sampledValues = [NSMutableArray arrayWithCapacity:easingSample.count];
|
||||||
|
for (NSNumber *sample in easingSample) {
|
||||||
|
CGFloat t = sample.CG_APPEND(, floatValue, doubleValue);
|
||||||
|
[sampledValues addObject:interpolationBlock(t)];
|
||||||
|
}
|
||||||
|
|
||||||
|
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:key];
|
||||||
|
animation.beginTime = CACurrentMediaTime() + delay / 1000.0;
|
||||||
|
animation.duration = duration / 1000.0;
|
||||||
|
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
|
||||||
|
animation.values = sampledValues;
|
||||||
|
|
||||||
|
[view.layer setValue:toValue forKey:key];
|
||||||
|
|
||||||
|
NSString *animationKey = [NSString stringWithFormat:@"RCT.%@.%@", animationTag, key];
|
||||||
|
[view.layer addAnimation:animation forKey:animationKey];
|
||||||
|
}];
|
||||||
|
|
||||||
|
strongSelf->_animationRegistry[animationTag] = reactTag;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stopAnimation:(NSNumber *)animationTag
|
||||||
|
{
|
||||||
|
RCT_EXPORT(stopAnimation);
|
||||||
|
|
||||||
|
__weak RCTAnimationManager *weakSelf = self;
|
||||||
|
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
|
RCTAnimationManager *strongSelf = weakSelf;
|
||||||
|
|
||||||
|
NSNumber *reactTag = strongSelf->_animationRegistry[animationTag];
|
||||||
|
if (!reactTag) return;
|
||||||
|
|
||||||
|
UIView *view = viewRegistry[reactTag];
|
||||||
|
for (NSString *animationKey in view.layer.animationKeys) {
|
||||||
|
if ([animationKey hasPrefix:@"RCT"]) {
|
||||||
|
NSRange periodLocation = [animationKey rangeOfString:@"." options:0 range:NSMakeRange(3, animationKey.length - 3)];
|
||||||
|
if (periodLocation.location != NSNotFound) {
|
||||||
|
NSInteger integerTag = [[animationKey substringWithRange:NSMakeRange(3, periodLocation.location)] integerValue];
|
||||||
|
if (animationTag.integerValue == integerTag) {
|
||||||
|
[view.layer removeAnimationForKey:animationKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strongSelf->_animationRegistry[animationTag] = nil;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -2,24 +2,25 @@
|
||||||
|
|
||||||
#import "RCTUIManager.h"
|
#import "RCTUIManager.h"
|
||||||
|
|
||||||
#import <AVFoundation/AVFoundation.h>
|
|
||||||
#import <objc/message.h>
|
#import <objc/message.h>
|
||||||
|
|
||||||
|
#import <AVFoundation/AVFoundation.h>
|
||||||
|
|
||||||
#import "Layout.h"
|
#import "Layout.h"
|
||||||
#import "RCTAnimationType.h"
|
#import "RCTAnimationType.h"
|
||||||
#import "RCTAssert.h"
|
#import "RCTAssert.h"
|
||||||
#import "RCTBridge.h"
|
#import "RCTBridge.h"
|
||||||
#import "RCTConvert.h"
|
#import "RCTConvert.h"
|
||||||
#import "RCTRootView.h"
|
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
#import "RCTNavigator.h"
|
#import "RCTNavigator.h"
|
||||||
|
#import "RCTRootView.h"
|
||||||
#import "RCTScrollableProtocol.h"
|
#import "RCTScrollableProtocol.h"
|
||||||
#import "RCTShadowView.h"
|
#import "RCTShadowView.h"
|
||||||
#import "RCTSparseArray.h"
|
#import "RCTSparseArray.h"
|
||||||
#import "RCTUtils.h"
|
#import "RCTUtils.h"
|
||||||
#import "RCTView.h"
|
#import "RCTView.h"
|
||||||
#import "RCTViewNodeProtocol.h"
|
|
||||||
#import "RCTViewManager.h"
|
#import "RCTViewManager.h"
|
||||||
|
#import "RCTViewNodeProtocol.h"
|
||||||
#import "UIView+ReactKit.h"
|
#import "UIView+ReactKit.h"
|
||||||
|
|
||||||
typedef void (^react_view_node_block_t)(id<RCTViewNodeProtocol>);
|
typedef void (^react_view_node_block_t)(id<RCTViewNodeProtocol>);
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
830A229E1A66C68A008503DA /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; };
|
830A229E1A66C68A008503DA /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; };
|
||||||
830BA4551A8E3BDA00D53203 /* RCTCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 830BA4541A8E3BDA00D53203 /* RCTCache.m */; };
|
830BA4551A8E3BDA00D53203 /* RCTCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 830BA4541A8E3BDA00D53203 /* RCTCache.m */; };
|
||||||
832348161A77A5AA00B55238 /* Layout.c in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FC71A68125100A75B9A /* Layout.c */; };
|
832348161A77A5AA00B55238 /* Layout.c in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FC71A68125100A75B9A /* Layout.c */; };
|
||||||
|
83C911101AAE6521001323A3 /* RCTAnimationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 83C9110F1AAE6521001323A3 /* RCTAnimationManager.m */; };
|
||||||
83CBBA511A601E3B00E9B192 /* RCTAssert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */; };
|
83CBBA511A601E3B00E9B192 /* RCTAssert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */; };
|
||||||
83CBBA521A601E3B00E9B192 /* RCTLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA4E1A601E3B00E9B192 /* RCTLog.m */; };
|
83CBBA521A601E3B00E9B192 /* RCTLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA4E1A601E3B00E9B192 /* RCTLog.m */; };
|
||||||
83CBBA531A601E3B00E9B192 /* RCTUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA501A601E3B00E9B192 /* RCTUtils.m */; };
|
83CBBA531A601E3B00E9B192 /* RCTUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA501A601E3B00E9B192 /* RCTUtils.m */; };
|
||||||
|
@ -153,6 +154,8 @@
|
||||||
830BA4541A8E3BDA00D53203 /* RCTCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTCache.m; sourceTree = "<group>"; };
|
830BA4541A8E3BDA00D53203 /* RCTCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTCache.m; sourceTree = "<group>"; };
|
||||||
83BEE46C1A6D19BC00B5863B /* RCTSparseArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSparseArray.h; sourceTree = "<group>"; };
|
83BEE46C1A6D19BC00B5863B /* RCTSparseArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSparseArray.h; sourceTree = "<group>"; };
|
||||||
83BEE46D1A6D19BC00B5863B /* RCTSparseArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSparseArray.m; sourceTree = "<group>"; };
|
83BEE46D1A6D19BC00B5863B /* RCTSparseArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSparseArray.m; sourceTree = "<group>"; };
|
||||||
|
83C9110E1AAE6521001323A3 /* RCTAnimationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAnimationManager.h; sourceTree = "<group>"; };
|
||||||
|
83C9110F1AAE6521001323A3 /* RCTAnimationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAnimationManager.m; sourceTree = "<group>"; };
|
||||||
83CBBA2E1A601D0E00E9B192 /* libReactKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libReactKit.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
83CBBA2E1A601D0E00E9B192 /* libReactKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libReactKit.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
83CBBA4A1A601E3B00E9B192 /* RCTAssert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAssert.h; sourceTree = "<group>"; };
|
83CBBA4A1A601E3B00E9B192 /* RCTAssert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAssert.h; sourceTree = "<group>"; };
|
||||||
83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAssert.m; sourceTree = "<group>"; };
|
83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAssert.m; sourceTree = "<group>"; };
|
||||||
|
@ -210,6 +213,8 @@
|
||||||
children = (
|
children = (
|
||||||
13B07FE71A69327A00A75B9A /* RCTAlertManager.h */,
|
13B07FE71A69327A00A75B9A /* RCTAlertManager.h */,
|
||||||
13B07FE81A69327A00A75B9A /* RCTAlertManager.m */,
|
13B07FE81A69327A00A75B9A /* RCTAlertManager.m */,
|
||||||
|
83C9110E1AAE6521001323A3 /* RCTAnimationManager.h */,
|
||||||
|
83C9110F1AAE6521001323A3 /* RCTAnimationManager.m */,
|
||||||
13B07FE91A69327A00A75B9A /* RCTExceptionsManager.h */,
|
13B07FE91A69327A00A75B9A /* RCTExceptionsManager.h */,
|
||||||
13B07FEA1A69327A00A75B9A /* RCTExceptionsManager.m */,
|
13B07FEA1A69327A00A75B9A /* RCTExceptionsManager.m */,
|
||||||
5F5F0D971A9E456B001279FA /* RCTLocationObserver.h */,
|
5F5F0D971A9E456B001279FA /* RCTLocationObserver.h */,
|
||||||
|
@ -458,6 +463,7 @@
|
||||||
13A1F71E1A75392D00D3D453 /* RCTKeyCommands.m in Sources */,
|
13A1F71E1A75392D00D3D453 /* RCTKeyCommands.m in Sources */,
|
||||||
83CBBA531A601E3B00E9B192 /* RCTUtils.m in Sources */,
|
83CBBA531A601E3B00E9B192 /* RCTUtils.m in Sources */,
|
||||||
14435CE61AAC4AE100FC20F4 /* RCTMapManager.m in Sources */,
|
14435CE61AAC4AE100FC20F4 /* RCTMapManager.m in Sources */,
|
||||||
|
83C911101AAE6521001323A3 /* RCTAnimationManager.m in Sources */,
|
||||||
83CBBA601A601EAA00E9B192 /* RCTBridge.m in Sources */,
|
83CBBA601A601EAA00E9B192 /* RCTBridge.m in Sources */,
|
||||||
58114A161AAE854800E7D092 /* RCTPicker.m in Sources */,
|
58114A161AAE854800E7D092 /* RCTPicker.m in Sources */,
|
||||||
137327E81AA5CF210034F82E /* RCTTabBarItem.m in Sources */,
|
137327E81AA5CF210034F82E /* RCTTabBarItem.m in Sources */,
|
||||||
|
|
Loading…
Reference in New Issue