diff --git a/Examples/UIExplorer/GeoLocationExample.js b/Examples/UIExplorer/GeolocationExample.js
similarity index 100%
rename from Examples/UIExplorer/GeoLocationExample.js
rename to Examples/UIExplorer/GeolocationExample.js
diff --git a/Examples/UIExplorer/SwitchExample.js b/Examples/UIExplorer/SwitchExample.js
new file mode 100644
index 000000000..9aa63833f
--- /dev/null
+++ b/Examples/UIExplorer/SwitchExample.js
@@ -0,0 +1,141 @@
+/**
+ * Copyright 2004-present Facebook. All Rights Reserved.
+ *
+ * @providesModule SwitchExample
+ */
+'use strict';
+
+var React = require('react-native');
+var {
+ SwitchIOS,
+ Text,
+ View
+} = React;
+
+var BasicSwitchExample = React.createClass({
+ getInitialState() {
+ return {
+ trueSwitchIsOn: true,
+ falseSwitchIsOn: false,
+ };
+ },
+ render() {
+ return (
+
+ this.setState({falseSwitchIsOn: value})}
+ style={{marginBottom: 10}}
+ value={this.state.falseSwitchIsOn} />
+ this.setState({trueSwitchIsOn: value})}
+ value={this.state.trueSwitchIsOn} />
+
+ );
+ }
+});
+
+var DisabledSwitchExample = React.createClass({
+ render() {
+ return (
+
+
+
+
+ );
+ },
+});
+
+var ColorSwitchExample = React.createClass({
+ getInitialState() {
+ return {
+ colorTrueSwitchIsOn: true,
+ colorFalseSwitchIsOn: false,
+ };
+ },
+ render() {
+ return (
+
+ this.setState({colorFalseSwitchIsOn: value})}
+ onTintColor="#00ff00"
+ style={{marginBottom: 10}}
+ thumbTintColor="#0000ff"
+ tintColor="#ff0000"
+ value={this.state.colorFalseSwitchIsOn} />
+ this.setState({colorTrueSwitchIsOn: value})}
+ onTintColor="#00ff00"
+ thumbTintColor="#0000ff"
+ tintColor="#ff0000"
+ value={this.state.colorTrueSwitchIsOn} />
+
+ );
+ },
+});
+
+var EventSwitchExample = React.createClass({
+ getInitialState() {
+ return {
+ eventSwitchIsOn: false,
+ eventSwitchRegressionIsOn: true,
+ };
+ },
+ render() {
+ return (
+
+
+ this.setState({eventSwitchIsOn: value})}
+ style={{marginBottom: 10}}
+ value={this.state.eventSwitchIsOn} />
+ this.setState({eventSwitchIsOn: value})}
+ style={{marginBottom: 10}}
+ value={this.state.eventSwitchIsOn} />
+ {this.state.eventSwitchIsOn ? "On" : "Off"}
+
+
+ this.setState({eventSwitchRegressionIsOn: value})}
+ style={{marginBottom: 10}}
+ value={this.state.eventSwitchRegressionIsOn} />
+ this.setState({eventSwitchRegressionIsOn: value})}
+ style={{marginBottom: 10}}
+ value={this.state.eventSwitchRegressionIsOn} />
+ {this.state.eventSwitchRegressionIsOn ? "On" : "Off"}
+
+
+ );
+ }
+});
+
+exports.title = '';
+exports.description = 'Native boolean input';
+exports.examples = [
+ {
+ title: 'Switches can be set to true or false',
+ render() { return ; }
+ },
+ {
+ title: 'Switches can be disabled',
+ render() { return ; }
+ },
+ {
+ title: 'Custom colors can be provided',
+ render() { return ; }
+ },
+ {
+ title: 'Change events can be detected',
+ render() { return ; }
+ },
+ {
+ title: 'Switches are controlled components',
+ render() { return ; }
+ }
+];
diff --git a/Examples/UIExplorer/UIExplorerList.js b/Examples/UIExplorer/UIExplorerList.js
index dd658b6ad..277517983 100644
--- a/Examples/UIExplorer/UIExplorerList.js
+++ b/Examples/UIExplorer/UIExplorerList.js
@@ -34,6 +34,7 @@ var EXAMPLES = [
require('./DatePickerExample'),
require('./GeolocationExample'),
require('./TabBarExample'),
+ require('./SwitchExample'),
];
var UIExplorerList = React.createClass({
diff --git a/Libraries/Components/SwitchIOS/SwitchIOS.android.js b/Libraries/Components/SwitchIOS/SwitchIOS.android.js
new file mode 100644
index 000000000..72c24fa28
--- /dev/null
+++ b/Libraries/Components/SwitchIOS/SwitchIOS.android.js
@@ -0,0 +1,41 @@
+/**
+ * Copyright 2004-present Facebook. All Rights Reserved.
+ *
+ * @providesModule SwitchIOS
+ */
+
+'use strict';
+
+var React = require('React');
+var StyleSheet = require('StyleSheet');
+var Text = require('Text');
+var View = require('View');
+
+var DummySwitchIOS = React.createClass({
+ render: function() {
+ return (
+
+ SwitchIOS is not supported on this platform!
+
+ );
+ },
+});
+
+var styles = StyleSheet.create({
+ dummySwitchIOS: {
+ width: 120,
+ height: 50,
+ backgroundColor: '#ffbcbc',
+ borderWidth: 1,
+ borderColor: 'red',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ text: {
+ color: '#333333',
+ margin: 5,
+ fontSize: 10,
+ }
+});
+
+module.exports = DummySwitchIOS;
diff --git a/Libraries/Components/SwitchIOS/SwitchIOS.ios.js b/Libraries/Components/SwitchIOS/SwitchIOS.ios.js
new file mode 100644
index 000000000..391b4da3a
--- /dev/null
+++ b/Libraries/Components/SwitchIOS/SwitchIOS.ios.js
@@ -0,0 +1,117 @@
+/**
+ * Copyright 2004-present Facebook. All Rights Reserved.
+ *
+ * @providesModule SwitchIOS
+ *
+ * This is a controlled component version of RKSwitch.
+ */
+'use strict';
+
+var NativeMethodsMixin = require('NativeMethodsMixin');
+var PropTypes = require('ReactPropTypes');
+var React = require('React');
+var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
+var StyleSheet = require('StyleSheet');
+
+var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
+var merge = require('merge');
+
+var SWITCH = 'switch';
+
+/**
+ * Use `SwitchIOS` to render a boolean input on iOS. This is
+ * a controlled component, so you must hook in to the `onValueChange` callback
+ * and update the `value` prop in order for the component to update, otherwise
+ * the user's change will be reverted immediately to reflect `props.value` as the
+ * source of truth.
+ */
+var SwitchIOS = React.createClass({
+ mixins: [NativeMethodsMixin],
+
+ propTypes: {
+ /**
+ * The value of the switch, if true the switch will be turned on.
+ * Default value is false.
+ */
+ value: PropTypes.bool,
+
+ /**
+ * If true the user won't be able to toggle the switch.
+ * Default value is false.
+ */
+ disabled: PropTypes.bool,
+
+ /**
+ * Callback that is called when the user toggles the switch.
+ */
+ onValueChange: PropTypes.func,
+
+ /**
+ * Background color when the switch is turned on.
+ */
+ onTintColor: PropTypes.string,
+
+ /**
+ * Background color for the switch round button.
+ */
+ thumbTintColor: PropTypes.string,
+
+ /**
+ * Background color when the switch is turned off.
+ */
+ tintColor: PropTypes.string,
+ },
+
+ getDefaultProps: function() {
+ return {
+ value: false,
+ disabled: false,
+ };
+ },
+
+ _onChange: function(event) {
+ this.props.onChange && this.props.onChange(event);
+ this.props.onValueChange && this.props.onValueChange(event.nativeEvent.value);
+
+ // The underlying switch might have changed, but we're controlled,
+ // and so want to ensure it represents our value.
+ this.refs[SWITCH].setNativeProps({on: this.props.value});
+ },
+
+ render: function() {
+ return (
+
+ );
+ }
+});
+
+var styles = StyleSheet.create({
+ rkSwitch: {
+ height: 31,
+ width: 51,
+ },
+});
+
+var rkSwitchAttributes = merge(ReactIOSViewAttributes.UIView, {
+ onTintColor: true,
+ tintColor: true,
+ thumbTintColor: true,
+ on: true,
+ enabled: true,
+});
+
+var RKSwitch = createReactIOSNativeComponentClass({
+ validAttributes: rkSwitchAttributes,
+ uiViewClassName: 'RCTSwitch',
+});
+
+module.exports = SwitchIOS;
diff --git a/Libraries/GeoLocation/RCTGeolocation.xcodeproj/project.pbxproj b/Libraries/GeoLocation/RCTGeolocation.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..94f9c3f91
--- /dev/null
+++ b/Libraries/GeoLocation/RCTGeolocation.xcodeproj/project.pbxproj
@@ -0,0 +1,256 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 134814061AA4E45400B7C361 /* RCTLocationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 134814051AA4E45400B7C361 /* RCTLocationObserver.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 58B511D91A9E6C8500147676 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "include/$(PRODUCT_NAME)";
+ dstSubfolderSpec = 16;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 134814041AA4E45400B7C361 /* RCTLocationObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTLocationObserver.h; sourceTree = ""; };
+ 134814051AA4E45400B7C361 /* RCTLocationObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTLocationObserver.m; sourceTree = ""; };
+ 134814201AA4EA6300B7C361 /* libRCTGeolocation.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTGeolocation.a; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 58B511D81A9E6C8500147676 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 134814211AA4EA7D00B7C361 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 134814201AA4EA6300B7C361 /* libRCTGeolocation.a */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 58B511D21A9E6C8500147676 = {
+ isa = PBXGroup;
+ children = (
+ 134814041AA4E45400B7C361 /* RCTLocationObserver.h */,
+ 134814051AA4E45400B7C361 /* RCTLocationObserver.m */,
+ 134814211AA4EA7D00B7C361 /* Products */,
+ );
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 58B511DA1A9E6C8500147676 /* RCTGeolocation */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTGeolocation" */;
+ buildPhases = (
+ 58B511D71A9E6C8500147676 /* Sources */,
+ 58B511D81A9E6C8500147676 /* Frameworks */,
+ 58B511D91A9E6C8500147676 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = RCTGeolocation;
+ productName = RCTDataManager;
+ productReference = 134814201AA4EA6300B7C361 /* libRCTGeolocation.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 58B511D31A9E6C8500147676 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0610;
+ ORGANIZATIONNAME = Facebook;
+ TargetAttributes = {
+ 58B511DA1A9E6C8500147676 = {
+ CreatedOnToolsVersion = 6.1.1;
+ };
+ };
+ };
+ buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTGeolocation" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 58B511D21A9E6C8500147676;
+ productRefGroup = 58B511D21A9E6C8500147676;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 58B511DA1A9E6C8500147676 /* RCTGeolocation */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 58B511D71A9E6C8500147676 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 134814061AA4E45400B7C361 /* RCTLocationObserver.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 58B511ED1A9E6C8500147676 /* 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;
+ 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;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.1;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 58B511EE1A9E6C8500147676 /* 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;
+ 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;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.1;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 58B511F01A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../ReactKit/**",
+ );
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "/Users/nicklockwood/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/ReactKit/build/Debug-iphoneos",
+ );
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = RCTGeolocation;
+ SKIP_INSTALL = YES;
+ };
+ name = Debug;
+ };
+ 58B511F11A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../ReactKit/**",
+ );
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "/Users/nicklockwood/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/ReactKit/build/Debug-iphoneos",
+ );
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = RCTGeolocation;
+ SKIP_INSTALL = YES;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTGeolocation" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511ED1A9E6C8500147676 /* Debug */,
+ 58B511EE1A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTGeolocation" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511F01A9E6C8500147676 /* Debug */,
+ 58B511F11A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 58B511D31A9E6C8500147676 /* Project object */;
+}
diff --git a/Libraries/react-native/react-native.js b/Libraries/react-native/react-native.js
index 944b9a53b..5aafb28ce 100644
--- a/Libraries/react-native/react-native.js
+++ b/Libraries/react-native/react-native.js
@@ -20,6 +20,7 @@ var ReactNative = {
ActivityIndicatorIOS: require('ActivityIndicatorIOS'),
StatusBarIOS: require('StatusBarIOS'),
StyleSheet: require('StyleSheet'),
+ SwitchIOS: require('SwitchIOS'),
Text: require('Text'),
TextInput: require('TextInput'),
TimerMixin: require('TimerMixin'),
diff --git a/ReactKit/ReactKit.xcodeproj/project.pbxproj b/ReactKit/ReactKit.xcodeproj/project.pbxproj
index 63dff04fb..dd9a452a0 100644
--- a/ReactKit/ReactKit.xcodeproj/project.pbxproj
+++ b/ReactKit/ReactKit.xcodeproj/project.pbxproj
@@ -35,6 +35,8 @@
13E067571A70F44B002CDEE1 /* RCTView.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E067501A70F44B002CDEE1 /* RCTView.m */; };
13E067591A70F44B002CDEE1 /* UIView+ReactKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E067541A70F44B002CDEE1 /* UIView+ReactKit.m */; };
58C571C11AA56C1900CDF9C8 /* RCTDatePickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */; };
+ 14F3620D1AABD06A001CE568 /* RCTSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F362081AABD06A001CE568 /* RCTSwitch.m */; };
+ 14F3620E1AABD06A001CE568 /* RCTSwitchManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F3620A1AABD06A001CE568 /* RCTSwitchManager.m */; };
830A229E1A66C68A008503DA /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; };
830BA4551A8E3BDA00D53203 /* RCTCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 830BA4541A8E3BDA00D53203 /* RCTCache.m */; };
832348161A77A5AA00B55238 /* Layout.c in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FC71A68125100A75B9A /* Layout.c */; };
@@ -125,6 +127,10 @@
13EFFCCF1A98E6FE002607DC /* RCTJSMethodRegistrar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJSMethodRegistrar.h; sourceTree = ""; };
58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDatePickerManager.m; sourceTree = ""; };
58C571C01AA56C1900CDF9C8 /* RCTDatePickerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDatePickerManager.h; sourceTree = ""; };
+ 14F362071AABD06A001CE568 /* RCTSwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSwitch.h; sourceTree = ""; };
+ 14F362081AABD06A001CE568 /* RCTSwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSwitch.m; sourceTree = ""; };
+ 14F362091AABD06A001CE568 /* RCTSwitchManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSwitchManager.h; sourceTree = ""; };
+ 14F3620A1AABD06A001CE568 /* RCTSwitchManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSwitchManager.m; sourceTree = ""; };
830213F31A654E0800B993E6 /* RCTBridgeModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTBridgeModule.h; sourceTree = ""; };
830A229C1A66C68A008503DA /* RCTRootView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootView.h; sourceTree = ""; };
830A229D1A66C68A008503DA /* RCTRootView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootView.m; sourceTree = ""; };
@@ -204,6 +210,10 @@
13B07FF31A6947C200A75B9A /* Views */ = {
isa = PBXGroup;
children = (
+ 14F362071AABD06A001CE568 /* RCTSwitch.h */,
+ 14F362081AABD06A001CE568 /* RCTSwitch.m */,
+ 14F362091AABD06A001CE568 /* RCTSwitchManager.h */,
+ 14F3620A1AABD06A001CE568 /* RCTSwitchManager.m */,
13442BF21AA90E0B0037E5B0 /* RCTAnimationType.h */,
58C571C01AA56C1900CDF9C8 /* RCTDatePickerManager.h */,
58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */,
@@ -398,6 +408,8 @@
83CBBA5A1A601E9000E9B192 /* RCTRedBox.m in Sources */,
83CBBA511A601E3B00E9B192 /* RCTAssert.m in Sources */,
832348161A77A5AA00B55238 /* Layout.c in Sources */,
+ 14F3620D1AABD06A001CE568 /* RCTSwitch.m in Sources */,
+ 14F3620E1AABD06A001CE568 /* RCTSwitchManager.m in Sources */,
13B080201A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.m in Sources */,
13E067561A70F44B002CDEE1 /* RCTViewManager.m in Sources */,
58C571C11AA56C1900CDF9C8 /* RCTDatePickerManager.m in Sources */,
diff --git a/ReactKit/Views/RCTSwitch.h b/ReactKit/Views/RCTSwitch.h
new file mode 100644
index 000000000..7866eb866
--- /dev/null
+++ b/ReactKit/Views/RCTSwitch.h
@@ -0,0 +1,10 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+
+#import
+
+@interface RCTSwitch : UISwitch
+
+@property (nonatomic, assign) BOOL wasOn;
+
+@end
diff --git a/ReactKit/Views/RCTSwitch.m b/ReactKit/Views/RCTSwitch.m
new file mode 100644
index 000000000..70233fede
--- /dev/null
+++ b/ReactKit/Views/RCTSwitch.m
@@ -0,0 +1,15 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+#import "RCTSwitch.h"
+
+#import "RCTEventDispatcher.h"
+#import "UIView+ReactKit.h"
+
+@implementation RCTSwitch
+
+- (void)setOn:(BOOL)on animated:(BOOL)animated {
+ _wasOn = on;
+ [super setOn:on animated:animated];
+}
+
+@end
diff --git a/ReactKit/Views/RCTSwitchManager.h b/ReactKit/Views/RCTSwitchManager.h
new file mode 100644
index 000000000..f6833d106
--- /dev/null
+++ b/ReactKit/Views/RCTSwitchManager.h
@@ -0,0 +1,7 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+#import "RCTViewManager.h"
+
+@interface RCTSwitchManager : RCTViewManager
+
+@end
diff --git a/ReactKit/Views/RCTSwitchManager.m b/ReactKit/Views/RCTSwitchManager.m
new file mode 100644
index 000000000..61eab8199
--- /dev/null
+++ b/ReactKit/Views/RCTSwitchManager.m
@@ -0,0 +1,39 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+#import "RCTSwitchManager.h"
+
+#import "RCTBridge.h"
+#import "RCTEventDispatcher.h"
+#import "RCTSwitch.h"
+#import "UIView+ReactKit.h"
+
+@implementation RCTSwitchManager
+
+- (UIView *)view
+{
+ RCTSwitch *switcher = [[RCTSwitch alloc] init];
+ [switcher addTarget:self
+ action:@selector(onChange:)
+ forControlEvents:UIControlEventValueChanged];
+ return switcher;
+}
+
+- (void)onChange:(RCTSwitch *)sender
+{
+ if (sender.wasOn != sender.on) {
+ [self.bridge.eventDispatcher sendInputEventWithName:@"topChange" body:@{
+ @"target": sender.reactTag,
+ @"value": @(sender.on)
+ }];
+
+ sender.wasOn = sender.on;
+ }
+}
+
+RCT_EXPORT_VIEW_PROPERTY(onTintColor);
+RCT_EXPORT_VIEW_PROPERTY(tintColor);
+RCT_EXPORT_VIEW_PROPERTY(thumbTintColor);
+RCT_EXPORT_VIEW_PROPERTY(on);
+RCT_EXPORT_VIEW_PROPERTY(enabled);
+
+@end