├── .gitignore ├── LICENSE ├── README.md ├── example ├── .flowconfig ├── .gitignore ├── .npmignore ├── example.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── example.xcscheme ├── exampleTests │ ├── Info.plist │ └── exampleTests.m ├── examples │ ├── CoverFlowExample.js │ ├── PageScrollerExample.js │ └── ScrollViewExample.js ├── iOS │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── LaunchScreen.xib │ ├── Images.xcassets │ │ ├── 0-cnn1.imageset │ │ │ ├── 0-cnn1@1x.png │ │ │ ├── 0-cnn1@2x.png │ │ │ ├── 0-cnn1@3x.png │ │ │ └── Contents.json │ │ ├── 1-facebook1.imageset │ │ │ ├── 1-facebook1@1x.jpeg │ │ │ ├── 1-facebook1@2x.jpeg │ │ │ ├── 1-facebook1@3x.jpeg │ │ │ └── Contents.json │ │ ├── 2-facebook2.imageset │ │ │ ├── 2-facebook2@1x.jpeg │ │ │ ├── 2-facebook2@2x.jpeg │ │ │ ├── 2-facebook2@3x.jpeg │ │ │ └── Contents.json │ │ ├── 3-flipboard1.imageset │ │ │ ├── 3-flipboard1@1x.png │ │ │ ├── 3-flipboard1@2x.png │ │ │ ├── 3-flipboard1@3x.png │ │ │ └── Contents.json │ │ ├── 4-flipboard2.imageset │ │ │ ├── 4-flipboard2@1x.png │ │ │ ├── 4-flipboard2@2x.png │ │ │ ├── 4-flipboard2@3x.png │ │ │ └── Contents.json │ │ ├── 5-messenger1.imageset │ │ │ ├── 5-messenger1@1x.png │ │ │ ├── 5-messenger1@2x.png │ │ │ ├── 5-messenger1@3x.png │ │ │ └── Contents.json │ │ ├── 6-nyt1.imageset │ │ │ ├── 6-nyt1@1x.jpeg │ │ │ ├── 6-nyt1@2x.jpeg │ │ │ ├── 6-nyt1@3x.jpeg │ │ │ └── Contents.json │ │ ├── 7-pages1.imageset │ │ │ ├── 7-pages1@1x.jpeg │ │ │ ├── 7-pages1@2x.jpeg │ │ │ ├── 7-pages1@3x.jpeg │ │ │ └── Contents.json │ │ ├── 8-vine1.imageset │ │ │ ├── 8-vine1@1x.png │ │ │ ├── 8-vine1@2x.png │ │ │ ├── 8-vine1@3x.png │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── main.jsbundle │ └── main.m ├── index.ios.js └── package.json ├── index.js ├── lib ├── CoverFlow.js ├── PageScroller.js ├── PanController.js ├── PullToRefresh.js └── ScrollView.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | 29 | 30 | .idea -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Leland Richardson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-pan-controller 2 | 3 | ## Motivation 4 | 5 | The `PanResponder` class in React Native is incredibly useful, and can handle a 6 | broad range of interactions/animatinos. Unfortunately, there are a lot of very 7 | common interactions/animations that require a lot of the same boilerplate 8 | in order to get them working properly, and that code is not necessarily straight 9 | forward. 10 | 11 | The `` component is intended to much more easily handle a lot of 12 | these common scenarios. See below for usage. 13 | 14 | 15 | ## Installation 16 | 17 | ```bash 18 | $ npm install --save react-native-pan-controller 19 | ``` 20 | 21 | 22 | 23 | 24 | ## API (props) 25 | 26 | ### Behavior Config 27 | 28 | | Prop | Default | Type | Description | 29 | | :------------ |:---------------:| :---------------:| :-----| 30 | | panX | `new Animated.Value(0)` | `Animated` | ... | 31 | | panY | `new Animated.Value(0)` | `Animated` | ... | 32 | | horizontal | `false` | `Boolean` | ... | 33 | | vertical | `false` | `Boolean` | ... | 34 | | lockDirection | `true` | `Boolean` | ... | 35 | | overshootX | `"spring"` | `"spring"|"clamp"` | ... | 36 | | overshootY | `"spring"` | `"spring"|"clamp"` | ... | 37 | | xMode | `"decay"` | `"decay"|"snap"|"spring-origin"` | ... | 38 | | yMode | `"decay"` | `"decay"|"snap"|"spring-origin"` | ... | 39 | | xBounds | `[-Infinity, Infinity]` | `Array` | ... | 40 | | yBounds | `[-Infinity, Infinity]` | `Array` | ... | 41 | | snapSpacingX | `null` | `Number` | ... | 42 | | snapSpacingY | `null` | `Number` | ... | 43 | 44 | ### Animation Config 45 | 46 | | Prop | Default | Type | Description | 47 | | :------------ |:---------------:| :---------------:| :-----| 48 | | overshootSpringConfig | `{ friction: 7, tension: 40 }` | `Object` | ... | 49 | | momentumDecayConfig | `{ deceleration: 0.993 }` | `Object` | ... | 50 | | springOriginConfig | `{ friction: 7, tension: 40 }` | `Object` | ... | 51 | | directionLockDistance | `10` | `Number` | ... | 52 | | overshootReductionFactor | `3` | `Number` | ... | 53 | 54 | ### Events 55 | 56 | | Prop | Parameters | Description | 57 | | :------------ | :---------------:| :-----| 58 | | onOvershoot | NO | ... | 59 | | onDirectionChange | NO | ... | 60 | | onReleaseX | NO | ... | 61 | | onReleaseY | NO | ... | 62 | | onRelease | NO | ... | 63 | 64 | 65 | 66 | 67 | 68 | ## Examples 69 | 70 | There is an example project where you can run and inspect all of the below 71 | examples if you want. In order to do so, you must first do the following: 72 | 73 | ```bash 74 | $ cd examples 75 | $ npm install 76 | ``` 77 | 78 | ### ScrollView 79 | 80 | ### CoverFlow 81 | 82 | ![](http://i.giphy.com/xTiTnh9zUTwf3oiHRK.gif) 83 | 84 | ### PageScroller 85 | 86 | ### PullToRefresh 87 | 88 | ![](http://i.giphy.com/xTiTnduykRpC513w4M.gif) 89 | 90 | ### Chat Heads 91 | 92 | ### Window Shade 93 | 94 | 95 | 96 | 97 | ## Contributing 98 | 99 | PR's welcome. Additionally, if you have an interaction that you think might be 100 | able to be handled by the `PanController`, but you're not quite sure how to 101 | implement it, give me an example of the interaction and I'll try to get it working 102 | and add an example. 103 | 104 | If it is not easily implemented using the `PanController`, but seems like a 105 | strong use-case, I may extend the implementation to handle it more easily. 106 | 107 | 108 | 109 | 110 | 111 | ## License 112 | 113 | MIT License. 114 | -------------------------------------------------------------------------------- /example/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | # We fork some components by platform. 4 | .*/*.web.js 5 | .*/*.android.js 6 | 7 | # Some modules have their own node_modules with overlap 8 | .*/node_modules/node-haste/.* 9 | 10 | # Ignore react-tools where there are overlaps, but don't ignore anything that 11 | # react-native relies on 12 | .*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js 13 | .*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js 14 | .*/node_modules/react-tools/src/browser/ui/React.js 15 | .*/node_modules/react-tools/src/core/ReactInstanceHandles.js 16 | .*/node_modules/react-tools/src/event/EventPropagators.js 17 | 18 | # Ignore commoner tests 19 | .*/node_modules/commoner/test/.* 20 | 21 | # See https://github.com/facebook/flow/issues/442 22 | .*/react-tools/node_modules/commoner/lib/reader.js 23 | 24 | # Ignore jest 25 | .*/react-native/node_modules/jest-cli/.* 26 | 27 | [include] 28 | 29 | [libs] 30 | node_modules/react-native/Libraries/react-native/react-native-interface.js 31 | 32 | [options] 33 | module.system=haste 34 | 35 | suppress_type=$FlowIssue 36 | suppress_type=$FlowFixMe 37 | suppress_type=$FixMe 38 | 39 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-3]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 40 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-3]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+ 41 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 42 | 43 | [version] 44 | 0.13.1 45 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # node.js 26 | # 27 | node_modules/ 28 | npm-debug.log 29 | -------------------------------------------------------------------------------- /example/.npmignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # node.js 25 | # 26 | node_modules/ 27 | npm-debug.log 28 | -------------------------------------------------------------------------------- /example/example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 008F07F31AC5B25A0029DE68 /* main.jsbundle in Resources */ = {isa = PBXBuildFile; fileRef = 008F07F21AC5B25A0029DE68 /* main.jsbundle */; }; 11 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 12 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; 13 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; 14 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; 15 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; 16 | 00E356F31AD99517003FC87E /* exampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* exampleTests.m */; }; 17 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; 18 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; 19 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 20 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 21 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 22 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 23 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 24 | 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 25 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 32 | proxyType = 2; 33 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 34 | remoteInfo = RCTActionSheet; 35 | }; 36 | 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 39 | proxyType = 2; 40 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 41 | remoteInfo = RCTGeolocation; 42 | }; 43 | 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { 44 | isa = PBXContainerItemProxy; 45 | containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 46 | proxyType = 2; 47 | remoteGlobalIDString = 58B5115D1A9E6B3D00147676; 48 | remoteInfo = RCTImage; 49 | }; 50 | 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = { 51 | isa = PBXContainerItemProxy; 52 | containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 53 | proxyType = 2; 54 | remoteGlobalIDString = 58B511DB1A9E6C8500147676; 55 | remoteInfo = RCTNetwork; 56 | }; 57 | 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = { 58 | isa = PBXContainerItemProxy; 59 | containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 60 | proxyType = 2; 61 | remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; 62 | remoteInfo = RCTVibration; 63 | }; 64 | 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { 65 | isa = PBXContainerItemProxy; 66 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; 67 | proxyType = 1; 68 | remoteGlobalIDString = 13B07F861A680F5B00A75B9A; 69 | remoteInfo = example; 70 | }; 71 | 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { 72 | isa = PBXContainerItemProxy; 73 | containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 74 | proxyType = 2; 75 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 76 | remoteInfo = RCTSettings; 77 | }; 78 | 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = { 79 | isa = PBXContainerItemProxy; 80 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 81 | proxyType = 2; 82 | remoteGlobalIDString = 3C86DF461ADF2C930047B81A; 83 | remoteInfo = RCTWebSocket; 84 | }; 85 | 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { 86 | isa = PBXContainerItemProxy; 87 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 88 | proxyType = 2; 89 | remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; 90 | remoteInfo = React; 91 | }; 92 | 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { 93 | isa = PBXContainerItemProxy; 94 | containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 95 | proxyType = 2; 96 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 97 | remoteInfo = RCTLinking; 98 | }; 99 | 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { 100 | isa = PBXContainerItemProxy; 101 | containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 102 | proxyType = 2; 103 | remoteGlobalIDString = 58B5119B1A9E6C1200147676; 104 | remoteInfo = RCTText; 105 | }; 106 | /* End PBXContainerItemProxy section */ 107 | 108 | /* Begin PBXFileReference section */ 109 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = main.jsbundle; path = iOS/main.jsbundle; sourceTree = ""; }; 110 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = ""; }; 111 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = ""; }; 112 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = node_modules/react-native/Libraries/Image/RCTImage.xcodeproj; sourceTree = ""; }; 113 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj; sourceTree = ""; }; 114 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = ""; }; 115 | 00E356EE1AD99517003FC87E /* exampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = exampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 116 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 117 | 00E356F21AD99517003FC87E /* exampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = exampleTests.m; sourceTree = ""; }; 118 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj; sourceTree = ""; }; 119 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = ""; }; 120 | 13B07F961A680F5B00A75B9A /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 121 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = iOS/AppDelegate.h; sourceTree = ""; }; 122 | 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = iOS/AppDelegate.m; sourceTree = ""; }; 123 | 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 124 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = iOS/Images.xcassets; sourceTree = ""; }; 125 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = iOS/Info.plist; sourceTree = ""; }; 126 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = iOS/main.m; sourceTree = ""; }; 127 | 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = node_modules/react-native/React/React.xcodeproj; sourceTree = ""; }; 128 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = ""; }; 129 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = node_modules/react-native/Libraries/Text/RCTText.xcodeproj; sourceTree = ""; }; 130 | /* End PBXFileReference section */ 131 | 132 | /* Begin PBXFrameworksBuildPhase section */ 133 | 00E356EB1AD99517003FC87E /* Frameworks */ = { 134 | isa = PBXFrameworksBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | ); 138 | runOnlyForDeploymentPostprocessing = 0; 139 | }; 140 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 141 | isa = PBXFrameworksBuildPhase; 142 | buildActionMask = 2147483647; 143 | files = ( 144 | 146834051AC3E58100842450 /* libReact.a in Frameworks */, 145 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 146 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, 147 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, 148 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, 149 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, 150 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, 151 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, 152 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, 153 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 154 | ); 155 | runOnlyForDeploymentPostprocessing = 0; 156 | }; 157 | /* End PBXFrameworksBuildPhase section */ 158 | 159 | /* Begin PBXGroup section */ 160 | 00C302A81ABCB8CE00DB3ED1 /* Products */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */, 164 | ); 165 | name = Products; 166 | sourceTree = ""; 167 | }; 168 | 00C302B61ABCB90400DB3ED1 /* Products */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, 172 | ); 173 | name = Products; 174 | sourceTree = ""; 175 | }; 176 | 00C302BC1ABCB91800DB3ED1 /* Products */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */, 180 | ); 181 | name = Products; 182 | sourceTree = ""; 183 | }; 184 | 00C302D41ABCB9D200DB3ED1 /* Products */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */, 188 | ); 189 | name = Products; 190 | sourceTree = ""; 191 | }; 192 | 00C302E01ABCB9EE00DB3ED1 /* Products */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */, 196 | ); 197 | name = Products; 198 | sourceTree = ""; 199 | }; 200 | 00E356EF1AD99517003FC87E /* exampleTests */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 00E356F21AD99517003FC87E /* exampleTests.m */, 204 | 00E356F01AD99517003FC87E /* Supporting Files */, 205 | ); 206 | path = exampleTests; 207 | sourceTree = ""; 208 | }; 209 | 00E356F01AD99517003FC87E /* Supporting Files */ = { 210 | isa = PBXGroup; 211 | children = ( 212 | 00E356F11AD99517003FC87E /* Info.plist */, 213 | ); 214 | name = "Supporting Files"; 215 | sourceTree = ""; 216 | }; 217 | 139105B71AF99BAD00B5F7CC /* Products */ = { 218 | isa = PBXGroup; 219 | children = ( 220 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, 221 | ); 222 | name = Products; 223 | sourceTree = ""; 224 | }; 225 | 139FDEE71B06529A00C62182 /* Products */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, 229 | ); 230 | name = Products; 231 | sourceTree = ""; 232 | }; 233 | 13B07FAE1A68108700A75B9A /* example */ = { 234 | isa = PBXGroup; 235 | children = ( 236 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */, 237 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 238 | 13B07FB01A68108700A75B9A /* AppDelegate.m */, 239 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 240 | 13B07FB61A68108700A75B9A /* Info.plist */, 241 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 242 | 13B07FB71A68108700A75B9A /* main.m */, 243 | ); 244 | name = example; 245 | sourceTree = ""; 246 | }; 247 | 146834001AC3E56700842450 /* Products */ = { 248 | isa = PBXGroup; 249 | children = ( 250 | 146834041AC3E56700842450 /* libReact.a */, 251 | ); 252 | name = Products; 253 | sourceTree = ""; 254 | }; 255 | 78C398B11ACF4ADC00677621 /* Products */ = { 256 | isa = PBXGroup; 257 | children = ( 258 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */, 259 | ); 260 | name = Products; 261 | sourceTree = ""; 262 | }; 263 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 264 | isa = PBXGroup; 265 | children = ( 266 | 146833FF1AC3E56700842450 /* React.xcodeproj */, 267 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 268 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, 269 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, 270 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 271 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, 272 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, 273 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, 274 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, 275 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, 276 | ); 277 | name = Libraries; 278 | sourceTree = ""; 279 | }; 280 | 832341B11AAA6A8300B99B32 /* Products */ = { 281 | isa = PBXGroup; 282 | children = ( 283 | 832341B51AAA6A8300B99B32 /* libRCTText.a */, 284 | ); 285 | name = Products; 286 | sourceTree = ""; 287 | }; 288 | 83CBB9F61A601CBA00E9B192 = { 289 | isa = PBXGroup; 290 | children = ( 291 | 13B07FAE1A68108700A75B9A /* example */, 292 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 293 | 00E356EF1AD99517003FC87E /* exampleTests */, 294 | 83CBBA001A601CBA00E9B192 /* Products */, 295 | ); 296 | indentWidth = 2; 297 | sourceTree = ""; 298 | tabWidth = 2; 299 | }; 300 | 83CBBA001A601CBA00E9B192 /* Products */ = { 301 | isa = PBXGroup; 302 | children = ( 303 | 13B07F961A680F5B00A75B9A /* example.app */, 304 | 00E356EE1AD99517003FC87E /* exampleTests.xctest */, 305 | ); 306 | name = Products; 307 | sourceTree = ""; 308 | }; 309 | /* End PBXGroup section */ 310 | 311 | /* Begin PBXNativeTarget section */ 312 | 00E356ED1AD99517003FC87E /* exampleTests */ = { 313 | isa = PBXNativeTarget; 314 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "exampleTests" */; 315 | buildPhases = ( 316 | 00E356EA1AD99517003FC87E /* Sources */, 317 | 00E356EB1AD99517003FC87E /* Frameworks */, 318 | 00E356EC1AD99517003FC87E /* Resources */, 319 | ); 320 | buildRules = ( 321 | ); 322 | dependencies = ( 323 | 00E356F51AD99517003FC87E /* PBXTargetDependency */, 324 | ); 325 | name = exampleTests; 326 | productName = exampleTests; 327 | productReference = 00E356EE1AD99517003FC87E /* exampleTests.xctest */; 328 | productType = "com.apple.product-type.bundle.unit-test"; 329 | }; 330 | 13B07F861A680F5B00A75B9A /* example */ = { 331 | isa = PBXNativeTarget; 332 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */; 333 | buildPhases = ( 334 | 13B07F871A680F5B00A75B9A /* Sources */, 335 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 336 | 13B07F8E1A680F5B00A75B9A /* Resources */, 337 | ); 338 | buildRules = ( 339 | ); 340 | dependencies = ( 341 | ); 342 | name = example; 343 | productName = "Hello World"; 344 | productReference = 13B07F961A680F5B00A75B9A /* example.app */; 345 | productType = "com.apple.product-type.application"; 346 | }; 347 | /* End PBXNativeTarget section */ 348 | 349 | /* Begin PBXProject section */ 350 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 351 | isa = PBXProject; 352 | attributes = { 353 | LastUpgradeCheck = 0610; 354 | ORGANIZATIONNAME = Facebook; 355 | TargetAttributes = { 356 | 00E356ED1AD99517003FC87E = { 357 | CreatedOnToolsVersion = 6.2; 358 | TestTargetID = 13B07F861A680F5B00A75B9A; 359 | }; 360 | }; 361 | }; 362 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "example" */; 363 | compatibilityVersion = "Xcode 3.2"; 364 | developmentRegion = English; 365 | hasScannedForEncodings = 0; 366 | knownRegions = ( 367 | en, 368 | Base, 369 | ); 370 | mainGroup = 83CBB9F61A601CBA00E9B192; 371 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 372 | projectDirPath = ""; 373 | projectReferences = ( 374 | { 375 | ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; 376 | ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 377 | }, 378 | { 379 | ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; 380 | ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 381 | }, 382 | { 383 | ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; 384 | ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 385 | }, 386 | { 387 | ProductGroup = 78C398B11ACF4ADC00677621 /* Products */; 388 | ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 389 | }, 390 | { 391 | ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; 392 | ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 393 | }, 394 | { 395 | ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; 396 | ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 397 | }, 398 | { 399 | ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; 400 | ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 401 | }, 402 | { 403 | ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */; 404 | ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 405 | }, 406 | { 407 | ProductGroup = 139FDEE71B06529A00C62182 /* Products */; 408 | ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 409 | }, 410 | { 411 | ProductGroup = 146834001AC3E56700842450 /* Products */; 412 | ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; 413 | }, 414 | ); 415 | projectRoot = ""; 416 | targets = ( 417 | 13B07F861A680F5B00A75B9A /* example */, 418 | 00E356ED1AD99517003FC87E /* exampleTests */, 419 | ); 420 | }; 421 | /* End PBXProject section */ 422 | 423 | /* Begin PBXReferenceProxy section */ 424 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = { 425 | isa = PBXReferenceProxy; 426 | fileType = archive.ar; 427 | path = libRCTActionSheet.a; 428 | remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; 429 | sourceTree = BUILT_PRODUCTS_DIR; 430 | }; 431 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { 432 | isa = PBXReferenceProxy; 433 | fileType = archive.ar; 434 | path = libRCTGeolocation.a; 435 | remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; 436 | sourceTree = BUILT_PRODUCTS_DIR; 437 | }; 438 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { 439 | isa = PBXReferenceProxy; 440 | fileType = archive.ar; 441 | path = libRCTImage.a; 442 | remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */; 443 | sourceTree = BUILT_PRODUCTS_DIR; 444 | }; 445 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = { 446 | isa = PBXReferenceProxy; 447 | fileType = archive.ar; 448 | path = libRCTNetwork.a; 449 | remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */; 450 | sourceTree = BUILT_PRODUCTS_DIR; 451 | }; 452 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = { 453 | isa = PBXReferenceProxy; 454 | fileType = archive.ar; 455 | path = libRCTVibration.a; 456 | remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; 457 | sourceTree = BUILT_PRODUCTS_DIR; 458 | }; 459 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { 460 | isa = PBXReferenceProxy; 461 | fileType = archive.ar; 462 | path = libRCTSettings.a; 463 | remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; 464 | sourceTree = BUILT_PRODUCTS_DIR; 465 | }; 466 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = { 467 | isa = PBXReferenceProxy; 468 | fileType = archive.ar; 469 | path = libRCTWebSocket.a; 470 | remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */; 471 | sourceTree = BUILT_PRODUCTS_DIR; 472 | }; 473 | 146834041AC3E56700842450 /* libReact.a */ = { 474 | isa = PBXReferenceProxy; 475 | fileType = archive.ar; 476 | path = libReact.a; 477 | remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; 478 | sourceTree = BUILT_PRODUCTS_DIR; 479 | }; 480 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { 481 | isa = PBXReferenceProxy; 482 | fileType = archive.ar; 483 | path = libRCTLinking.a; 484 | remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; 485 | sourceTree = BUILT_PRODUCTS_DIR; 486 | }; 487 | 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { 488 | isa = PBXReferenceProxy; 489 | fileType = archive.ar; 490 | path = libRCTText.a; 491 | remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; 492 | sourceTree = BUILT_PRODUCTS_DIR; 493 | }; 494 | /* End PBXReferenceProxy section */ 495 | 496 | /* Begin PBXResourcesBuildPhase section */ 497 | 00E356EC1AD99517003FC87E /* Resources */ = { 498 | isa = PBXResourcesBuildPhase; 499 | buildActionMask = 2147483647; 500 | files = ( 501 | ); 502 | runOnlyForDeploymentPostprocessing = 0; 503 | }; 504 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 505 | isa = PBXResourcesBuildPhase; 506 | buildActionMask = 2147483647; 507 | files = ( 508 | 008F07F31AC5B25A0029DE68 /* main.jsbundle in Resources */, 509 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 510 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, 511 | ); 512 | runOnlyForDeploymentPostprocessing = 0; 513 | }; 514 | /* End PBXResourcesBuildPhase section */ 515 | 516 | /* Begin PBXSourcesBuildPhase section */ 517 | 00E356EA1AD99517003FC87E /* Sources */ = { 518 | isa = PBXSourcesBuildPhase; 519 | buildActionMask = 2147483647; 520 | files = ( 521 | 00E356F31AD99517003FC87E /* exampleTests.m in Sources */, 522 | ); 523 | runOnlyForDeploymentPostprocessing = 0; 524 | }; 525 | 13B07F871A680F5B00A75B9A /* Sources */ = { 526 | isa = PBXSourcesBuildPhase; 527 | buildActionMask = 2147483647; 528 | files = ( 529 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, 530 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 531 | ); 532 | runOnlyForDeploymentPostprocessing = 0; 533 | }; 534 | /* End PBXSourcesBuildPhase section */ 535 | 536 | /* Begin PBXTargetDependency section */ 537 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { 538 | isa = PBXTargetDependency; 539 | target = 13B07F861A680F5B00A75B9A /* example */; 540 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; 541 | }; 542 | /* End PBXTargetDependency section */ 543 | 544 | /* Begin PBXVariantGroup section */ 545 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { 546 | isa = PBXVariantGroup; 547 | children = ( 548 | 13B07FB21A68108700A75B9A /* Base */, 549 | ); 550 | name = LaunchScreen.xib; 551 | path = iOS; 552 | sourceTree = ""; 553 | }; 554 | /* End PBXVariantGroup section */ 555 | 556 | /* Begin XCBuildConfiguration section */ 557 | 00E356F61AD99517003FC87E /* Debug */ = { 558 | isa = XCBuildConfiguration; 559 | buildSettings = { 560 | BUNDLE_LOADER = "$(TEST_HOST)"; 561 | FRAMEWORK_SEARCH_PATHS = ( 562 | "$(SDKROOT)/Developer/Library/Frameworks", 563 | "$(inherited)", 564 | ); 565 | GCC_PREPROCESSOR_DEFINITIONS = ( 566 | "DEBUG=1", 567 | "$(inherited)", 568 | ); 569 | INFOPLIST_FILE = exampleTests/Info.plist; 570 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 571 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 572 | PRODUCT_NAME = "$(TARGET_NAME)"; 573 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/example"; 574 | }; 575 | name = Debug; 576 | }; 577 | 00E356F71AD99517003FC87E /* Release */ = { 578 | isa = XCBuildConfiguration; 579 | buildSettings = { 580 | BUNDLE_LOADER = "$(TEST_HOST)"; 581 | COPY_PHASE_STRIP = NO; 582 | FRAMEWORK_SEARCH_PATHS = ( 583 | "$(SDKROOT)/Developer/Library/Frameworks", 584 | "$(inherited)", 585 | ); 586 | INFOPLIST_FILE = exampleTests/Info.plist; 587 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 588 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 589 | PRODUCT_NAME = "$(TARGET_NAME)"; 590 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/example"; 591 | }; 592 | name = Release; 593 | }; 594 | 13B07F941A680F5B00A75B9A /* Debug */ = { 595 | isa = XCBuildConfiguration; 596 | buildSettings = { 597 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 598 | HEADER_SEARCH_PATHS = ( 599 | "$(inherited)", 600 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 601 | "$(SRCROOT)/node_modules/react-native/React/**", 602 | ); 603 | INFOPLIST_FILE = "iOS/Info.plist"; 604 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 605 | OTHER_LDFLAGS = "-ObjC"; 606 | PRODUCT_NAME = example; 607 | }; 608 | name = Debug; 609 | }; 610 | 13B07F951A680F5B00A75B9A /* Release */ = { 611 | isa = XCBuildConfiguration; 612 | buildSettings = { 613 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 614 | HEADER_SEARCH_PATHS = ( 615 | "$(inherited)", 616 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 617 | "$(SRCROOT)/node_modules/react-native/React/**", 618 | ); 619 | INFOPLIST_FILE = "iOS/Info.plist"; 620 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 621 | OTHER_LDFLAGS = "-ObjC"; 622 | PRODUCT_NAME = example; 623 | }; 624 | name = Release; 625 | }; 626 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 627 | isa = XCBuildConfiguration; 628 | buildSettings = { 629 | ALWAYS_SEARCH_USER_PATHS = NO; 630 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 631 | CLANG_CXX_LIBRARY = "libc++"; 632 | CLANG_ENABLE_MODULES = YES; 633 | CLANG_ENABLE_OBJC_ARC = YES; 634 | CLANG_WARN_BOOL_CONVERSION = YES; 635 | CLANG_WARN_CONSTANT_CONVERSION = YES; 636 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 637 | CLANG_WARN_EMPTY_BODY = YES; 638 | CLANG_WARN_ENUM_CONVERSION = YES; 639 | CLANG_WARN_INT_CONVERSION = YES; 640 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 641 | CLANG_WARN_UNREACHABLE_CODE = YES; 642 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 643 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 644 | COPY_PHASE_STRIP = NO; 645 | ENABLE_STRICT_OBJC_MSGSEND = YES; 646 | GCC_C_LANGUAGE_STANDARD = gnu99; 647 | GCC_DYNAMIC_NO_PIC = NO; 648 | GCC_OPTIMIZATION_LEVEL = 0; 649 | GCC_PREPROCESSOR_DEFINITIONS = ( 650 | "DEBUG=1", 651 | "$(inherited)", 652 | ); 653 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 654 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 655 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 656 | GCC_WARN_UNDECLARED_SELECTOR = YES; 657 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 658 | GCC_WARN_UNUSED_FUNCTION = YES; 659 | GCC_WARN_UNUSED_VARIABLE = YES; 660 | HEADER_SEARCH_PATHS = ( 661 | "$(inherited)", 662 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 663 | "$(SRCROOT)/node_modules/react-native/React/**", 664 | ); 665 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 666 | MTL_ENABLE_DEBUG_INFO = YES; 667 | ONLY_ACTIVE_ARCH = YES; 668 | SDKROOT = iphoneos; 669 | }; 670 | name = Debug; 671 | }; 672 | 83CBBA211A601CBA00E9B192 /* Release */ = { 673 | isa = XCBuildConfiguration; 674 | buildSettings = { 675 | ALWAYS_SEARCH_USER_PATHS = NO; 676 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 677 | CLANG_CXX_LIBRARY = "libc++"; 678 | CLANG_ENABLE_MODULES = YES; 679 | CLANG_ENABLE_OBJC_ARC = YES; 680 | CLANG_WARN_BOOL_CONVERSION = YES; 681 | CLANG_WARN_CONSTANT_CONVERSION = YES; 682 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 683 | CLANG_WARN_EMPTY_BODY = YES; 684 | CLANG_WARN_ENUM_CONVERSION = YES; 685 | CLANG_WARN_INT_CONVERSION = YES; 686 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 687 | CLANG_WARN_UNREACHABLE_CODE = YES; 688 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 689 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 690 | COPY_PHASE_STRIP = YES; 691 | ENABLE_NS_ASSERTIONS = NO; 692 | ENABLE_STRICT_OBJC_MSGSEND = YES; 693 | GCC_C_LANGUAGE_STANDARD = gnu99; 694 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 695 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 696 | GCC_WARN_UNDECLARED_SELECTOR = YES; 697 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 698 | GCC_WARN_UNUSED_FUNCTION = YES; 699 | GCC_WARN_UNUSED_VARIABLE = YES; 700 | HEADER_SEARCH_PATHS = ( 701 | "$(inherited)", 702 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 703 | "$(SRCROOT)/node_modules/react-native/React/**", 704 | ); 705 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 706 | MTL_ENABLE_DEBUG_INFO = NO; 707 | SDKROOT = iphoneos; 708 | VALIDATE_PRODUCT = YES; 709 | }; 710 | name = Release; 711 | }; 712 | /* End XCBuildConfiguration section */ 713 | 714 | /* Begin XCConfigurationList section */ 715 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "exampleTests" */ = { 716 | isa = XCConfigurationList; 717 | buildConfigurations = ( 718 | 00E356F61AD99517003FC87E /* Debug */, 719 | 00E356F71AD99517003FC87E /* Release */, 720 | ); 721 | defaultConfigurationIsVisible = 0; 722 | defaultConfigurationName = Release; 723 | }; 724 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */ = { 725 | isa = XCConfigurationList; 726 | buildConfigurations = ( 727 | 13B07F941A680F5B00A75B9A /* Debug */, 728 | 13B07F951A680F5B00A75B9A /* Release */, 729 | ); 730 | defaultConfigurationIsVisible = 0; 731 | defaultConfigurationName = Release; 732 | }; 733 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "example" */ = { 734 | isa = XCConfigurationList; 735 | buildConfigurations = ( 736 | 83CBBA201A601CBA00E9B192 /* Debug */, 737 | 83CBBA211A601CBA00E9B192 /* Release */, 738 | ); 739 | defaultConfigurationIsVisible = 0; 740 | defaultConfigurationName = Release; 741 | }; 742 | /* End XCConfigurationList section */ 743 | }; 744 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 745 | } 746 | -------------------------------------------------------------------------------- /example/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /example/exampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /example/exampleTests/exampleTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | #import 12 | 13 | #import "RCTAssert.h" 14 | #import "RCTRedBox.h" 15 | #import "RCTRootView.h" 16 | 17 | #define TIMEOUT_SECONDS 240 18 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 19 | 20 | @interface exampleTests : XCTestCase 21 | 22 | @end 23 | 24 | @implementation exampleTests 25 | 26 | 27 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 28 | { 29 | if (test(view)) { 30 | return YES; 31 | } 32 | for (UIView *subview in [view subviews]) { 33 | if ([self findSubviewInView:subview matching:test]) { 34 | return YES; 35 | } 36 | } 37 | return NO; 38 | } 39 | 40 | - (void)testRendersWelcomeScreen { 41 | UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; 42 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 43 | BOOL foundElement = NO; 44 | NSString *redboxError = nil; 45 | 46 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 47 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 48 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 49 | 50 | redboxError = [[RCTRedBox sharedInstance] currentErrorMessage]; 51 | 52 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 53 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 54 | return YES; 55 | } 56 | return NO; 57 | }]; 58 | } 59 | 60 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 61 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 62 | } 63 | 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /example/examples/CoverFlowExample.js: -------------------------------------------------------------------------------- 1 | var React = require('react-native'); 2 | var { 3 | Image 4 | } = React; 5 | var { CoverFlow } = require('react-native-pan-controller'); 6 | 7 | var CoverFlowExample = React.createClass({ 8 | getInitialState() { 9 | return { 10 | images: [ 11 | require('image!0-cnn1'), 12 | require('image!1-facebook1'), 13 | require('image!2-facebook2'), 14 | require('image!3-flipboard1'), 15 | require('image!4-flipboard2'), 16 | require('image!5-messenger1'), 17 | require('image!6-nyt1'), 18 | require('image!7-pages1'), 19 | require('image!8-vine1'), 20 | ], 21 | }; 22 | }, 23 | render() { 24 | return ( 25 | 26 | {this.state.images.map((src, i) => )} 27 | 28 | ); 29 | } 30 | }); 31 | 32 | module.exports = CoverFlowExample; 33 | -------------------------------------------------------------------------------- /example/examples/PageScrollerExample.js: -------------------------------------------------------------------------------- 1 | var React = require('react-native'); 2 | var { 3 | Image, 4 | StyleSheet, 5 | Dimensions, 6 | } = React; 7 | var { PageScroller } = require('react-native-pan-controller'); 8 | var { width, height } = Dimensions.get('window'); 9 | var PageScrollerExample = React.createClass({ 10 | getInitialState() { 11 | return { 12 | images: [ 13 | require('image!0-cnn1'), 14 | require('image!1-facebook1'), 15 | require('image!2-facebook2'), 16 | require('image!3-flipboard1'), 17 | require('image!4-flipboard2'), 18 | require('image!5-messenger1'), 19 | require('image!6-nyt1'), 20 | require('image!7-pages1'), 21 | require('image!8-vine1'), 22 | ] 23 | }; 24 | }, 25 | onRemove(i) { 26 | this.setState({ 27 | images: this.state.images.slice(i, 1) 28 | }); 29 | }, 30 | render() { 31 | return ( 32 | 33 | {this.state.images.map((src, i) => )} 34 | 35 | ); 36 | } 37 | }); 38 | 39 | var styles = StyleSheet.create({ 40 | image: { 41 | // position: 'absolute', 42 | // top: (width - 200) / 2, 43 | // left: (height - 200) / 2, 44 | width: 240, 45 | height: 400, 46 | resizeMode: 'cover' 47 | } 48 | }) 49 | 50 | module.exports = PageScrollerExample; 51 | -------------------------------------------------------------------------------- /example/examples/ScrollViewExample.js: -------------------------------------------------------------------------------- 1 | var React = require('react-native'); 2 | var { 3 | View, 4 | StyleSheet, 5 | Animated, 6 | Text, 7 | } = React; 8 | var { ScrollView } = require('react-native-pan-controller'); 9 | var views = Array(200).join(".").split(""); 10 | 11 | var ScrollViewExample = React.createClass({ 12 | getInitialState() { 13 | return { 14 | scroll: new Animated.Value(0), 15 | text: "0", 16 | }; 17 | }, 18 | componentDidMount() { 19 | this.state.scroll.addListener(({ value}) => { 20 | this.setState({ text: value }); 21 | }); 22 | }, 23 | render() { 24 | return ( 25 | 26 | {views.map((src, i) => ( 27 | 28 | {this.state.text} 29 | 30 | ))} 31 | 32 | ); 33 | } 34 | }); 35 | 36 | var styles = StyleSheet.create({ 37 | view: { 38 | height: 40, 39 | borderWidth: 1, 40 | borderColor: '#ccc', 41 | } 42 | }) 43 | 44 | module.exports = ScrollViewExample; 45 | -------------------------------------------------------------------------------- /example/iOS/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /example/iOS/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AppDelegate.h" 11 | 12 | #import "RCTRootView.h" 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | NSURL *jsCodeLocation; 19 | 20 | /** 21 | * Loading JavaScript code - uncomment the one you want. 22 | * 23 | * OPTION 1 24 | * Load from development server. Start the server from the repository root: 25 | * 26 | * $ npm start 27 | * 28 | * To run on device, change `localhost` to the IP address of your computer 29 | * (you can get this by typing `ifconfig` into the terminal and selecting the 30 | * `inet` value under `en0:`) and make sure your computer and iOS device are 31 | * on the same Wi-Fi network. 32 | */ 33 | 34 | jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"]; 35 | 36 | /** 37 | * OPTION 2 38 | * Load from pre-bundled file on disk. To re-generate the static bundle 39 | * from the root of your project directory, run 40 | * 41 | * $ react-native bundle --minify 42 | * 43 | * see http://facebook.github.io/react-native/docs/runningondevice.html 44 | */ 45 | 46 | // jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 47 | 48 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 49 | moduleName:@"example" 50 | launchOptions:launchOptions]; 51 | 52 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 53 | UIViewController *rootViewController = [[UIViewController alloc] init]; 54 | rootViewController.view = rootView; 55 | self.window.rootViewController = rootViewController; 56 | [self.window makeKeyAndVisible]; 57 | return YES; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /example/iOS/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/0-cnn1.imageset/0-cnn1@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/0-cnn1.imageset/0-cnn1@1x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/0-cnn1.imageset/0-cnn1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/0-cnn1.imageset/0-cnn1@2x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/0-cnn1.imageset/0-cnn1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/0-cnn1.imageset/0-cnn1@3x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/0-cnn1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "0-cnn1@1x.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "0-cnn1@2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "0-cnn1@3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/1-facebook1.imageset/1-facebook1@1x.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/1-facebook1.imageset/1-facebook1@1x.jpeg -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/1-facebook1.imageset/1-facebook1@2x.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/1-facebook1.imageset/1-facebook1@2x.jpeg -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/1-facebook1.imageset/1-facebook1@3x.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/1-facebook1.imageset/1-facebook1@3x.jpeg -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/1-facebook1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "1-facebook1@1x.jpeg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "1-facebook1@2x.jpeg" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "1-facebook1@3x.jpeg" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/2-facebook2.imageset/2-facebook2@1x.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/2-facebook2.imageset/2-facebook2@1x.jpeg -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/2-facebook2.imageset/2-facebook2@2x.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/2-facebook2.imageset/2-facebook2@2x.jpeg -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/2-facebook2.imageset/2-facebook2@3x.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/2-facebook2.imageset/2-facebook2@3x.jpeg -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/2-facebook2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "2-facebook2@1x.jpeg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "2-facebook2@2x.jpeg" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "2-facebook2@3x.jpeg" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/3-flipboard1.imageset/3-flipboard1@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/3-flipboard1.imageset/3-flipboard1@1x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/3-flipboard1.imageset/3-flipboard1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/3-flipboard1.imageset/3-flipboard1@2x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/3-flipboard1.imageset/3-flipboard1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/3-flipboard1.imageset/3-flipboard1@3x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/3-flipboard1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "3-flipboard1@1x.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "3-flipboard1@2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "3-flipboard1@3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/4-flipboard2.imageset/4-flipboard2@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/4-flipboard2.imageset/4-flipboard2@1x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/4-flipboard2.imageset/4-flipboard2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/4-flipboard2.imageset/4-flipboard2@2x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/4-flipboard2.imageset/4-flipboard2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/4-flipboard2.imageset/4-flipboard2@3x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/4-flipboard2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "4-flipboard2@1x.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "4-flipboard2@2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "4-flipboard2@3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/5-messenger1.imageset/5-messenger1@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/5-messenger1.imageset/5-messenger1@1x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/5-messenger1.imageset/5-messenger1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/5-messenger1.imageset/5-messenger1@2x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/5-messenger1.imageset/5-messenger1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/5-messenger1.imageset/5-messenger1@3x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/5-messenger1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "5-messenger1@1x.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "5-messenger1#2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "5-messenger1@3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/6-nyt1.imageset/6-nyt1@1x.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/6-nyt1.imageset/6-nyt1@1x.jpeg -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/6-nyt1.imageset/6-nyt1@2x.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/6-nyt1.imageset/6-nyt1@2x.jpeg -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/6-nyt1.imageset/6-nyt1@3x.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/6-nyt1.imageset/6-nyt1@3x.jpeg -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/6-nyt1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "6-nyt1@1x.jpeg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "6-nyt1@2x.jpeg" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "6-nyt1@3x.jpeg" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/7-pages1.imageset/7-pages1@1x.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/7-pages1.imageset/7-pages1@1x.jpeg -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/7-pages1.imageset/7-pages1@2x.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/7-pages1.imageset/7-pages1@2x.jpeg -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/7-pages1.imageset/7-pages1@3x.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/7-pages1.imageset/7-pages1@3x.jpeg -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/7-pages1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "7-pages1@1x.jpeg" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "7-pages1@2x.jpeg" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "7-pages1@3x.jpeg" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/8-vine1.imageset/8-vine1@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/8-vine1.imageset/8-vine1@1x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/8-vine1.imageset/8-vine1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/8-vine1.imageset/8-vine1@2x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/8-vine1.imageset/8-vine1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/example/iOS/Images.xcassets/8-vine1.imageset/8-vine1@3x.png -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/8-vine1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "8-vine1@1x.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "8-vine1@2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "8-vine1@3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /example/iOS/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /example/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | NSLocationWhenInUseUsageDescription 40 | 41 | NSAppTransportSecurity 42 | 43 | 44 | NSAllowsArbitraryLoads 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /example/iOS/main.jsbundle: -------------------------------------------------------------------------------- 1 | // Offline JS 2 | // To re-generate the offline bundle, run this from the root of your project: 3 | // 4 | // $ react-native bundle --minify 5 | // 6 | // See http://facebook.github.io/react-native/docs/runningondevice.html for more details. 7 | 8 | throw new Error('Offline JS file is empty. See iOS/main.jsbundle for instructions'); 9 | -------------------------------------------------------------------------------- /example/iOS/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /example/index.ios.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | */ 5 | 'use strict'; 6 | 7 | var React = require('react-native'); 8 | var { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View, 13 | } = React; 14 | 15 | var CoverFlowExample = require('./examples/CoverFlowExample'); 16 | var PageScrollerExample = require('./examples/PageScrollerExample'); 17 | var ScrollViewExample = require('./examples/ScrollViewExample'); 18 | 19 | var example = React.createClass({ 20 | render: function() { 21 | return 22 | // return 23 | // return 24 | } 25 | }); 26 | 27 | AppRegistry.registerComponent('example', () => example); 28 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node_modules/react-native/packager/packager.sh" 7 | }, 8 | "dependencies": { 9 | "react-native": "^0.8.0", 10 | "react-native-pan-controller": "file:.." 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | PanController: require('./lib/PanController'), 3 | PageScroller: require('./lib/PageScroller'), 4 | CoverFlow: require('./lib/CoverFlow'), 5 | ScrollView: require('./lib/ScrollView'), 6 | }; 7 | -------------------------------------------------------------------------------- /lib/CoverFlow.js: -------------------------------------------------------------------------------- 1 | var React = require('react-native'); 2 | var { 3 | StyleSheet, 4 | Animated, 5 | PropTypes, 6 | Dimensions, 7 | } = React; 8 | var { width, height } = Dimensions.get('window'); 9 | 10 | var PanController = require('./PanController'); 11 | 12 | var CoverFlow = React.createClass({ 13 | 14 | propTypes: { 15 | scroll: PropTypes.any, // animated 16 | spacing: PropTypes.number, 17 | dCenter: PropTypes.number, 18 | }, 19 | 20 | getDefaultProps() { 21 | return { 22 | scroll: new Animated.Value(0), 23 | spacing: 200, 24 | dCenter: 120, 25 | }; 26 | }, 27 | 28 | render() { 29 | var { children, spacing, scroll, dCenter } = this.props; 30 | 31 | return ( 32 | 40 | {children.map((child, i) => { 41 | var dx = scroll.interpolate({ 42 | inputRange: [ spacing*i, spacing*(i+1)], 43 | outputRange: [ 0, spacing] 44 | }); 45 | var translateX = dx; 46 | // var perspective = dx.interpolate({ 47 | // inputRange: [-dCenter-1, -dCenter, 0, dCenter, dCenter+1], 48 | // outputRange: [400, 400, 100, 400, 400] 49 | // }); 50 | var translateY = dx.interpolate({ 51 | inputRange: [-dCenter-1, -dCenter, 0, dCenter, dCenter+1], 52 | outputRange: [ 0, 0, -10, 0, 0] 53 | }); 54 | var scale = dx.interpolate({ 55 | inputRange: [-dCenter-1, -dCenter, 0, dCenter, dCenter+1], 56 | outputRange: [ 1, 1, 1.6, 1, 1] 57 | }); 58 | // var rotateY = dx.interpolate({ 59 | // inputRange: [-dCenter-1, -dCenter, 0, dCenter, dCenter+1], 60 | // outputRange: [ '35deg', '35deg', '0deg', '-35deg', '-35deg'] 61 | // }); 62 | 63 | return ( 64 | 75 | {child} 76 | 77 | ); 78 | })} 79 | 80 | ); 81 | } 82 | }); 83 | 84 | var styles = StyleSheet.create({ 85 | container: { 86 | flex: 1, 87 | justifyContent: 'flex-start', 88 | alignItems: 'center', 89 | backgroundColor: '#2e2f31', 90 | padding: 30, 91 | }, 92 | image: { 93 | position: 'absolute', 94 | top: (width - 200) / 2, 95 | left: (height - 200) / 2, 96 | width: 200, 97 | height: 200, 98 | resizeMode: 'cover', 99 | } 100 | }); 101 | 102 | module.exports = CoverFlow; 103 | -------------------------------------------------------------------------------- /lib/PageScroller.js: -------------------------------------------------------------------------------- 1 | var React = require('react-native'); 2 | var { 3 | StyleSheet, 4 | View, 5 | Animated, 6 | PropTypes, 7 | Dimensions, 8 | Easing, 9 | Interpolation, 10 | } = React; 11 | var { width, height } = Dimensions.get('window'); //TODO: monitor for orientation change 12 | 13 | var PanController = require('./PanController'); 14 | 15 | var easing = Easing.bezier(.56,.17,.57,.85, (1000 / 60 / 4000) / 4); 16 | 17 | var PageScroller = React.createClass({ 18 | 19 | propTypes: { 20 | panY: PropTypes.instanceOf(Animated.Value), 21 | panX: PropTypes.instanceOf(Animated.Value), 22 | pageX: PropTypes.number, 23 | pageY: PropTypes.number, 24 | startY: PropTypes.number, 25 | onRemove: PropTypes.func, 26 | }, 27 | 28 | getDefaultProps() { 29 | return { 30 | panY: new Animated.Value(0), 31 | panX: new Animated.Value(0), 32 | pageX: 240, 33 | pageY: 400, 34 | startY: 50, 35 | } 36 | }, 37 | 38 | getInitialState() { 39 | return { 40 | swipeIndex: null, 41 | }; 42 | }, 43 | 44 | onDirectionChange(dir, { dy, dx, y0 }) { 45 | this.setState({ 46 | swipeIndex: dir === 'x' ? this.cardIndexFor(y0, this.props.panY._offset + dy, this.props.children.length) : null 47 | }); 48 | }, 49 | 50 | onReleaseX({ vx, vy, dx, dy }) { 51 | var { panX } = this.props; 52 | panX.flattenOffset(); 53 | 54 | var x = panX._value; 55 | var i = this.state.swipeIndex; 56 | if (x > 30) { 57 | // to the right... 58 | Animated.spring(panX, { 59 | toValue: 400, 60 | velocity: vx 61 | }).start(() => { 62 | if (this.props.onRemove) { 63 | this.props.onRemove(i); 64 | } 65 | }); 66 | return false; 67 | } else if (x < -30) { 68 | Animated.spring(panX, { 69 | toValue: -400, 70 | velocity: vx 71 | }).start(() => { 72 | if (this.props.onRemove) { 73 | this.props.onRemove(i); 74 | } 75 | }); 76 | return false; 77 | } 78 | return true; 79 | }, 80 | 81 | cardIndexFor(y0, panY, length) { 82 | var result = null; 83 | var h = this.props.pageY * 0.6; 84 | for (var i = 0; i < length; i++) { 85 | var hx = h * (length - i - 1); 86 | var hxm = Math.max(hx-h, 0); 87 | // y0 is the position they started the touch on the screen 88 | // panY is the current animated value 89 | var translateY = Interpolation.create({ 90 | inputRange: [0, hxm, hx+1, height+hx], 91 | outputRange: [0, 0, 10, 30 + height], 92 | easing: easing 93 | })(panY); 94 | 95 | var scale = Interpolation.create({ 96 | inputRange: [0, hx+1, 0.8*height+hx, height+hx, height + hx + 1], 97 | outputRange: [1, 1, 1.4, 1.3, 1.3] 98 | })(panY); 99 | 100 | var cardTop = this.props.startY + translateY - (scale - 1) / 2 * this.props.pageY; 101 | 102 | if (cardTop < y0) { 103 | result = i; 104 | } 105 | } 106 | return result; 107 | }, 108 | 109 | render: function () { 110 | var { panY, panX, children, pageY, pageX, startY } = this.props; 111 | var { swipeIndex } = this.state; 112 | var h = pageY * 0.6; 113 | var MIN = 240; 114 | var MAX = 1900; //TODO: compute from pageY + children.length... 115 | return ( 116 | 127 | {children.map((child, i) => { 128 | var x = children.length - i - 1; 129 | var hx = h * x; 130 | var hxm = Math.max(hx-h, 0); 131 | 132 | var translateX = i === swipeIndex ? panX : 0; 133 | 134 | var translateY = panY.interpolate({ 135 | inputRange: [0, hxm, hx+1, height+hx], 136 | outputRange: [0, 0, 10, 30 + height], 137 | easing: easing 138 | }); 139 | 140 | var scale = panY.interpolate({ 141 | inputRange: [0, hx+1, 0.8*height+hx, height+hx, height + hx + 1], 142 | outputRange: [1, 1, 1.4, 1.3, 1.3] 143 | }); 144 | 145 | return ( 146 | 161 | {child} 162 | 163 | ); 164 | })} 165 | 166 | ); 167 | } 168 | }); 169 | 170 | var styles = StyleSheet.create({ 171 | container: { 172 | flex: 1, 173 | justifyContent: 'center', 174 | alignItems: 'center', 175 | backgroundColor: '#2e2f31', 176 | }, 177 | }); 178 | 179 | module.exports = PageScroller; 180 | -------------------------------------------------------------------------------- /lib/PanController.js: -------------------------------------------------------------------------------- 1 | var React = require('react-native'); 2 | var { 3 | View, 4 | Animated, 5 | PropTypes, 6 | PanResponder, 7 | } = React; 8 | 9 | var ModePropType = PropTypes.oneOf(["decay", "snap", "spring-origin"]); 10 | var OvershootPropType = PropTypes.oneOf(["spring", "clamp"]); 11 | var AnimatedPropType = PropTypes.any; 12 | 13 | var PanController = React.createClass({ 14 | 15 | propTypes: { 16 | // Component Config 17 | lockDirection: PropTypes.bool, 18 | horizontal: PropTypes.bool, 19 | vertical: PropTypes.bool, 20 | overshootX: OvershootPropType, 21 | overshootY: OvershootPropType, 22 | xBounds: PropTypes.arrayOf(PropTypes.number), 23 | yBounds: PropTypes.arrayOf(PropTypes.number), 24 | xMode: ModePropType, 25 | yMode: ModePropType, 26 | snapSpacingX: PropTypes.number, // TODO: also allow an array of values? 27 | snapSpacingY: PropTypes.number, 28 | 29 | // Animated Values 30 | panX: AnimatedPropType, 31 | panY: AnimatedPropType, 32 | 33 | // Animation Config 34 | overshootSpringConfig: PropTypes.any, 35 | momentumDecayConfig: PropTypes.any, 36 | springOriginConfig: PropTypes.any, 37 | directionLockDistance: PropTypes.number, 38 | overshootReductionFactor: PropTypes.number, 39 | 40 | // Events 41 | onOvershoot: PropTypes.func, 42 | onDirectionChange: PropTypes.func, 43 | onReleaseX: PropTypes.func, 44 | onReleaseY: PropTypes.func, 45 | onRelease: PropTypes.func, 46 | 47 | //...PanResponderPropTypes, 48 | }, 49 | 50 | getDefaultProps() { 51 | return { 52 | horizontal: false, 53 | vertical: false, 54 | lockDirection: true, 55 | overshootX: "spring", 56 | overshootY: "spring", 57 | panX: new Animated.Value(0), 58 | panY: new Animated.Value(0), 59 | xBounds: [-Infinity, Infinity], 60 | yBounds: [-Infinity, Infinity], 61 | yMode: "decay", 62 | xMode: "decay", 63 | overshootSpringConfig: { friction: 7, tension: 40 }, 64 | momentumDecayConfig: { deceleration: 0.993 }, 65 | springOriginConfig: { friction: 7, tension: 40 }, 66 | overshootReductionFactor: 3, 67 | directionLockDistance: 10, 68 | onStartShouldSetPanResponder: () => true, 69 | onMoveShouldSetPanResponder: () => true, 70 | }; 71 | }, 72 | 73 | // getInitialState() { 74 | // //TODO: 75 | // // it's possible we want to move some props over to state. 76 | // // For example, xBounds/yBounds might need to be 77 | // // calculated/updated automatically 78 | // // 79 | // // This could also be done with a higher-order component 80 | // // that just massages props passed in... 81 | // return { 82 | // 83 | // }; 84 | // }, 85 | 86 | _responder: null, 87 | _listener: null, 88 | _direction: null, 89 | 90 | componentWillMount() { 91 | this._responder = PanResponder.create({ 92 | onStartShouldSetPanResponder: this.props.onStartShouldSetPanResponder, 93 | onMoveShouldSetPanResponder: this.props.onMoveShouldSetPanResponder, 94 | onPanResponderGrant: (...args) => { 95 | if (this.props.onPanResponderGrant) { 96 | this.props.onPanResponderGrant(...args); 97 | } 98 | var { panX, panY, horizontal, vertical, xMode, yMode } = this.props; 99 | 100 | this.handleResponderGrant(panX, xMode); 101 | this.handleResponderGrant(panY, yMode); 102 | 103 | this._direction = horizontal && !vertical ? 'x' : (vertical && !horizontal ? 'y' : null); 104 | }, 105 | onPanResponderMove: (_, { dx, dy, x0, y0 }) => { 106 | var { 107 | panX, 108 | panY, 109 | xBounds, 110 | yBounds, 111 | overshootX, 112 | overshootY, 113 | horizontal, 114 | vertical, 115 | lockDirection, 116 | directionLockDistance, 117 | } = this.props; 118 | 119 | if (!this._direction) { 120 | var dx2 = dx*dx; 121 | var dy2 = dy*dy; 122 | if (dx2 + dy2 > directionLockDistance) { 123 | this._direction = dx2 > dy2 ? 'x' : 'y'; 124 | if (this.props.onDirectionChange) { 125 | this.props.onDirectionChange(this._direction, { dx, dy, x0, y0 }); 126 | } 127 | } 128 | } 129 | 130 | var dir = this._direction; 131 | 132 | if (this.props.onPanResponderMove) { 133 | this.props.onPanResponderMove(_, { dx, dy, x0, y0 }); 134 | } 135 | 136 | if (horizontal && (!lockDirection || dir === 'x')) { 137 | var [xMin, xMax] = xBounds; 138 | 139 | this.handleResponderMove(panX, dx, xMin, xMax, overshootX); 140 | } 141 | 142 | if (vertical && (!lockDirection || dir === 'y')) { 143 | var [yMin, yMax] = yBounds; 144 | 145 | this.handleResponderMove(panY, dy, yMin, yMax, overshootY); 146 | } 147 | }, 148 | onPanResponderRelease: (_, { vx, vy, dx, dy }) => { 149 | var { 150 | panX, 151 | panY, 152 | xBounds, 153 | yBounds, 154 | overshootX, 155 | overshootY, 156 | horizontal, 157 | vertical, 158 | lockDirection, 159 | xMode, 160 | yMode, 161 | snapSpacingX, 162 | snapSpacingY, 163 | } = this.props; 164 | 165 | var cancel = false; 166 | 167 | var dir = this._direction; 168 | 169 | if (this.props.onRelease) { 170 | cancel = false === this.props.onRelease({ vx, vy, dx, dy }); 171 | } 172 | 173 | if (!cancel && horizontal && (!lockDirection || dir === 'x')) { 174 | var [xMin, xMax] = xBounds; 175 | if (this.props.onReleaseX) { 176 | cancel = false === this.props.onReleaseX({ vx, vy, dx, dy }); 177 | } 178 | !cancel && this.handleResponderRelease(panX, xMin, xMax, vx, overshootX, xMode, snapSpacingX); 179 | } 180 | 181 | if (!cancel && vertical && (!lockDirection || dir === 'y')) { 182 | var [yMin, yMax] = yBounds; 183 | if (this.props.onReleaseY) { 184 | cancel = false === this.props.onReleaseY({ vx, vy, dx, dy }); 185 | } 186 | !cancel && this.handleResponderRelease(panY, yMin, yMax, vy, overshootY, yMode, snapSpacingY); 187 | } 188 | 189 | this._direction = horizontal && !vertical ? 'x' : (vertical && !horizontal ? 'y' : null); 190 | } 191 | }); 192 | }, 193 | 194 | handleResponderMove(anim, delta, min, max, overshoot) { 195 | var val = anim._offset + delta; 196 | 197 | if (val > max) { 198 | switch (overshoot) { 199 | case "spring": 200 | val = max + (val - max) / this.props.overshootReductionFactor; 201 | break; 202 | case "clamp": 203 | val = max; 204 | break; 205 | } 206 | } 207 | if (val < min) { 208 | switch (overshoot) { 209 | case "spring": 210 | val = min - (min - val) / this.props.overshootReductionFactor; 211 | break; 212 | case "clamp": 213 | val = min; 214 | break; 215 | } 216 | } 217 | val = val - anim._offset; 218 | anim.setValue(val); 219 | }, 220 | 221 | handleResponderRelease(anim, min, max, velocity, overshoot, mode, snapSpacing) { 222 | anim.flattenOffset(); 223 | 224 | if (anim._value < min) { 225 | if (this.props.onOvershoot) { 226 | this.props.onOvershoot(); //TODO: what args should we pass to this 227 | } 228 | switch (overshoot) { 229 | case "spring": 230 | Animated.spring(anim, { 231 | ...this.props.overshootSpringConfig, 232 | toValue: min, 233 | velocity, 234 | }).start(); 235 | break; 236 | case "clamp": 237 | anim.setValue(min); 238 | break; 239 | } 240 | } else if (anim._value > max) { 241 | if (this.props.onOvershoot) { 242 | this.props.onOvershoot(); //TODO: what args should we pass to this 243 | } 244 | switch (overshoot) { 245 | case "spring": 246 | Animated.spring(anim, { 247 | ...this.props.overshootSpringConfig, 248 | toValue: max, 249 | velocity, 250 | }).start(); 251 | break; 252 | case "clamp": 253 | anim.setValue(min); 254 | break; 255 | } 256 | } else { 257 | 258 | switch (mode) { 259 | case "snap": 260 | this.handleSnappedScroll(anim, min, max, velocity, snapSpacing, overshoot); 261 | break; 262 | 263 | case "decay": 264 | this.handleMomentumScroll(anim, min, max, velocity, overshoot); 265 | break; 266 | 267 | case "spring-origin": 268 | Animated.spring(anim, { 269 | ...this.props.springOriginConfig, 270 | toValue: 0, 271 | velocity, 272 | }).start(); 273 | break; 274 | } 275 | } 276 | }, 277 | 278 | handleResponderGrant(anim, mode) { 279 | switch (mode) { 280 | case "spring-origin": 281 | anim.setValue(0); 282 | break; 283 | case "snap": 284 | case "decay": 285 | anim.setOffset(anim._value + anim._offset); 286 | anim.setValue(0); 287 | break; 288 | } 289 | }, 290 | 291 | handleMomentumScroll(anim, min, max, velocity, overshoot) { 292 | Animated.decay(anim, { 293 | ...this.props.momentumDecayConfig, 294 | velocity, 295 | }).start(() => { 296 | anim.removeListener(this._listener); 297 | }); 298 | 299 | this._listener = anim.addListener(({ value }) => { 300 | if (value < min) { 301 | anim.removeListener(this._listener); 302 | if (this.props.onOvershoot) { 303 | this.props.onOvershoot(); //TODO: what args should we pass to this 304 | } 305 | switch (overshoot) { 306 | case "spring": 307 | Animated.spring(anim, { 308 | ...this.props.overshootSpringConfig, 309 | toValue: min, 310 | velocity, 311 | }).start(); 312 | break; 313 | case "clamp": 314 | anim.setValue(min); 315 | break; 316 | } 317 | } else if (value > max) { 318 | anim.removeListener(this._listener); 319 | if (this.props.onOvershoot) { 320 | this.props.onOvershoot(); //TODO: what args should we pass to this 321 | } 322 | switch (overshoot) { 323 | case "spring": 324 | Animated.spring(anim, { 325 | ...this.props.overshootSpringConfig, 326 | toValue: max, 327 | velocity, 328 | }).start(); 329 | break; 330 | case "clamp": 331 | anim.setValue(min); 332 | break; 333 | } 334 | } 335 | }); 336 | }, 337 | 338 | handleSnappedScroll(anim, min, max, velocity, spacing) { 339 | var endX = this.momentumCenter(anim._value, velocity, spacing); 340 | endX = Math.max(endX, min); 341 | endX = Math.min(endX, max); 342 | var bounds = [endX-spacing/2, endX+spacing/2]; 343 | var endV = this.velocityAtBounds(anim._value, velocity, bounds); 344 | 345 | this._listener = anim.addListener(( { value } ) => { 346 | if (value > bounds[0] && value < bounds[1]) { 347 | Animated.spring(anim, { 348 | toValue: endX, 349 | velocity: endV, 350 | }).start(); 351 | } 352 | }); 353 | 354 | Animated.decay(anim, { 355 | ...this.props.momentumDecayConfig, 356 | velocity, 357 | }).start(()=> { 358 | anim.removeListener(this._listener); 359 | }); 360 | }, 361 | 362 | closestCenter(x, spacing) { 363 | var plus = (x % spacing) < spacing / 2 ? 0 : spacing; 364 | return Math.floor(x / spacing) * spacing + plus; 365 | }, 366 | 367 | momentumCenter(x0, vx, spacing) { 368 | var t = 0; 369 | var deceleration = this.props.momentumDecayConfig.deceleration || 0.997; 370 | var x1 = x0; 371 | var x = x1; 372 | 373 | while (true) { 374 | t += 16; 375 | x = x0 + (vx / (1 - deceleration)) * 376 | (1 - Math.exp(-(1 - deceleration) * t)); 377 | if (Math.abs(x-x1) < 0.1) { 378 | x1 = x; 379 | break; 380 | } 381 | x1 = x; 382 | } 383 | return this.closestCenter(x1, spacing); 384 | }, 385 | 386 | velocityAtBounds(x0, vx, bounds) { 387 | var t = 0; 388 | var deceleration = this.props.momentumDecayConfig.deceleration || 0.997; 389 | var x1 = x0; 390 | var x = x1; 391 | var vf; 392 | while (true) { 393 | t += 16; 394 | x = x0 + (vx / (1 - deceleration)) * 395 | (1 - Math.exp(-(1 - deceleration) * t)); 396 | vf = (x-x1) / 16; 397 | if (x > bounds[0] && x < bounds[1]) { 398 | break; 399 | } 400 | if (Math.abs(vf) < 0.1) { 401 | break; 402 | } 403 | x1 = x; 404 | } 405 | return vf; 406 | }, 407 | 408 | //componentDidMount() { 409 | // //TODO: we may need to measure the children width/height here? 410 | //}, 411 | // 412 | //componentWillUnmount() { 413 | // 414 | //}, 415 | // 416 | //componentDidUnmount() { 417 | // 418 | //}, 419 | 420 | render: function () { 421 | return 422 | } 423 | }); 424 | 425 | module.exports = PanController; 426 | -------------------------------------------------------------------------------- /lib/PullToRefresh.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lelandrichardson/react-native-pan-controller/8725378b83403a790511ac9860766b13fb78e995/lib/PullToRefresh.js -------------------------------------------------------------------------------- /lib/ScrollView.js: -------------------------------------------------------------------------------- 1 | var React = require('react-native'); 2 | var { 3 | StyleSheet, 4 | Animated, 5 | PropTypes, 6 | } = React; 7 | var PanController = require('./PanController'); 8 | 9 | var ScrollView = React.createClass({ 10 | 11 | propTypes: { 12 | scroll: PropTypes.instanceOf(Animated.Value), 13 | }, 14 | 15 | getDefaultProps() { 16 | return { 17 | scroll: new Animated.Value(0), 18 | }; 19 | }, 20 | 21 | render() { 22 | var { scroll, children } = this.props; 23 | return ( 24 | 30 | 35 | {children} 36 | 37 | 38 | ); 39 | } 40 | }); 41 | 42 | var styles = StyleSheet.create({ 43 | container: { 44 | flex: 1, 45 | }, 46 | }); 47 | 48 | module.exports = ScrollView; 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-pan-controller", 3 | "version": "0.0.1", 4 | "description": "A react native component to help with common use cases for scrolling/panning/etc", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/lelandrichardson/react-native-pan-controller.git" 12 | }, 13 | "keywords": [ 14 | "react", 15 | "react", 16 | "native", 17 | "react", 18 | "component", 19 | "panning", 20 | "scrolling", 21 | "touch", 22 | "animation" 23 | ], 24 | "author": "Leland Richardson", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/lelandrichardson/react-native-pan-controller/issues" 28 | }, 29 | "homepage": "https://github.com/lelandrichardson/react-native-pan-controller#readme", 30 | "peerDependencies": { 31 | "react-native": ">=0.8.0 || 0.8.0-rc || 0.8.0-rc.2 || 0.9.0-rc || 0.9.0-rc.2" 32 | } 33 | } 34 | --------------------------------------------------------------------------------