react-native-gesture-handler 2.8.0 → 2.9.0
Sign up to get free protection for your applications and to get access to all the features.
- package/RNGestureHandler.podspec +1 -1
- package/android/build.gradle +45 -43
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +1 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEvent.kt +14 -2
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +5 -1
- package/android/src/main/jni/CMakeLists.txt +10 -44
- package/android/src/main/jni/cpp-adapter.cpp +16 -13
- package/ios/Handlers/RNFlingHandler.m +39 -37
- package/ios/Handlers/RNForceTouchHandler.m +19 -17
- package/ios/Handlers/RNLongPressHandler.m +20 -22
- package/ios/Handlers/RNManualHandler.m +2 -3
- package/ios/Handlers/RNNativeViewHandler.mm +92 -88
- package/ios/Handlers/RNPanHandler.m +28 -32
- package/ios/Handlers/RNPinchHandler.m +9 -10
- package/ios/Handlers/RNRotationHandler.m +11 -14
- package/ios/Handlers/RNTapHandler.m +26 -26
- package/ios/RNGestureHandler.h +31 -24
- package/ios/RNGestureHandler.m +278 -273
- package/ios/RNGestureHandlerActionType.h +6 -4
- package/ios/RNGestureHandlerButton.m +11 -12
- package/ios/RNGestureHandlerButtonManager.m +6 -5
- package/ios/RNGestureHandlerDirection.h +4 -4
- package/ios/RNGestureHandlerEvents.h +3 -4
- package/ios/RNGestureHandlerEvents.m +114 -119
- package/ios/RNGestureHandlerManager.h +1 -2
- package/ios/RNGestureHandlerModule.h +1 -2
- package/ios/RNGestureHandlerModule.mm +126 -122
- package/ios/RNGestureHandlerPointerTracker.h +1 -1
- package/ios/RNGestureHandlerPointerTracker.m +40 -37
- package/ios/RNGestureHandlerRegistry.h +3 -1
- package/ios/RNGestureHandlerRegistry.m +24 -22
- package/ios/RNGestureHandlerState.h +6 -6
- package/ios/RNGestureHandlerStateManager.h +1 -1
- package/ios/RNManualActivationRecognizer.m +9 -9
- package/ios/RNRootViewGestureRecognizer.m +36 -39
- package/lib/commonjs/components/DrawerLayout.js.map +1 -1
- package/lib/commonjs/components/Swipeable.js.map +1 -1
- package/lib/commonjs/gestureHandlerRootHOC.js +2 -1
- package/lib/commonjs/gestureHandlerRootHOC.js.map +1 -1
- package/lib/commonjs/handlers/LongPressGestureHandler.js +3 -1
- package/lib/commonjs/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/commonjs/handlers/TapGestureHandler.js +3 -1
- package/lib/commonjs/handlers/TapGestureHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector.js +70 -28
- package/lib/commonjs/handlers/gestures/GestureDetector.js.map +1 -1
- package/lib/commonjs/handlers/gestures/longPressGesture.js +1 -0
- package/lib/commonjs/handlers/gestures/longPressGesture.js.map +1 -1
- package/lib/commonjs/handlers/gestures/tapGesture.js +1 -0
- package/lib/commonjs/handlers/gestures/tapGesture.js.map +1 -1
- package/lib/commonjs/web/handlers/LongPressGestureHandler.js +0 -1
- package/lib/commonjs/web/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/TapGestureHandler.js +0 -1
- package/lib/commonjs/web/handlers/TapGestureHandler.js.map +1 -1
- package/lib/module/components/DrawerLayout.js.map +1 -1
- package/lib/module/components/Swipeable.js.map +1 -1
- package/lib/module/gestureHandlerRootHOC.js +2 -1
- package/lib/module/gestureHandlerRootHOC.js.map +1 -1
- package/lib/module/handlers/LongPressGestureHandler.js +3 -1
- package/lib/module/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/module/handlers/TapGestureHandler.js +3 -1
- package/lib/module/handlers/TapGestureHandler.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector.js +72 -29
- package/lib/module/handlers/gestures/GestureDetector.js.map +1 -1
- package/lib/module/handlers/gestures/longPressGesture.js +1 -0
- package/lib/module/handlers/gestures/longPressGesture.js.map +1 -1
- package/lib/module/handlers/gestures/tapGesture.js +1 -0
- package/lib/module/handlers/gestures/tapGesture.js.map +1 -1
- package/lib/module/web/handlers/LongPressGestureHandler.js +0 -1
- package/lib/module/web/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/TapGestureHandler.js +0 -1
- package/lib/module/web/handlers/TapGestureHandler.js.map +1 -1
- package/lib/typescript/components/DrawerLayout.d.ts +3 -1
- package/lib/typescript/components/Swipeable.d.ts +3 -2
- package/lib/typescript/fabric/RNGestureHandlerButtonNativeComponent.d.ts +1 -1
- package/lib/typescript/fabric/RNGestureHandlerRootViewNativeComponent.d.ts +1 -1
- package/lib/typescript/gestureHandlerRootHOC.d.ts +1 -1
- package/package.json +4 -5
- package/src/components/DrawerLayout.tsx +8 -4
- package/src/components/Swipeable.tsx +14 -9
- package/src/gestureHandlerRootHOC.tsx +4 -1
- package/src/handlers/LongPressGestureHandler.ts +3 -1
- package/src/handlers/TapGestureHandler.ts +3 -1
- package/src/handlers/gestures/GestureDetector.tsx +81 -28
- package/src/handlers/gestures/longPressGesture.ts +1 -0
- package/src/handlers/gestures/tapGesture.ts +1 -0
- package/src/web/handlers/LongPressGestureHandler.ts +0 -1
- package/src/web/handlers/TapGestureHandler.ts +0 -1
package/RNGestureHandler.podspec
CHANGED
@@ -2,7 +2,7 @@ require "json"
|
|
2
2
|
|
3
3
|
fabric_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
|
4
4
|
|
5
|
-
isUserApp = File.
|
5
|
+
isUserApp = File.exist?(File.join(__dir__, "..", "..", "node_modules", "react-native", "package.json"))
|
6
6
|
if isUserApp
|
7
7
|
libInstances = %x[find ../../ -name "package.json" | grep "/react-native-gesture-handler/package.json" | grep -v "/.yarn/"]
|
8
8
|
libInstancesArray = libInstances.split("\n")
|
package/android/build.gradle
CHANGED
@@ -27,25 +27,33 @@ def isNewArchitectureEnabled() {
|
|
27
27
|
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
28
28
|
}
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
// Node's module resolution algorithm searches up to the root directory,
|
33
|
-
// after which the base path will be null
|
34
|
-
while (basePath) {
|
35
|
-
def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName)
|
36
|
-
if (candidatePath.toFile().exists()) {
|
37
|
-
return candidatePath.toString()
|
38
|
-
}
|
39
|
-
basePath = basePath.getParent()
|
40
|
-
}
|
41
|
-
return null
|
30
|
+
def safeExtGet(prop, fallback) {
|
31
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
42
32
|
}
|
43
33
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
34
|
+
def resolveReactNativeDirectory() {
|
35
|
+
def reactNativeLocation = safeExtGet("REACT_NATIVE_NODE_MODULES_DIR", null)
|
36
|
+
if (reactNativeLocation != null) {
|
37
|
+
return file(reactNativeLocation)
|
38
|
+
}
|
39
|
+
|
40
|
+
// monorepo workaround
|
41
|
+
// react-native can be hoisted or in project's own node_modules
|
42
|
+
def reactNativeFromProjectNodeModules = file("${rootProject.projectDir}/../node_modules/react-native")
|
43
|
+
if (reactNativeFromProjectNodeModules.exists()) {
|
44
|
+
return reactNativeFromProjectNodeModules
|
45
|
+
}
|
46
|
+
|
47
|
+
def reactNativeFromNodeModulesWithReanimated = file("${projectDir}/../../react-native")
|
48
|
+
if (reactNativeFromNodeModulesWithReanimated.exists()) {
|
49
|
+
return reactNativeFromNodeModulesWithReanimated
|
50
|
+
}
|
51
|
+
|
52
|
+
throw new Exception(
|
53
|
+
"[react-native-gesture-handler] Unable to resolve react-native location in " +
|
54
|
+
"node_modules. You should add project extension property (in app/build.gradle) " +
|
55
|
+
"`REACT_NATIVE_NODE_MODULES_DIR` with path to react-native."
|
56
|
+
)
|
49
57
|
}
|
50
58
|
|
51
59
|
if (isNewArchitectureEnabled()) {
|
@@ -58,10 +66,6 @@ if (project == rootProject) {
|
|
58
66
|
apply from: "spotless.gradle"
|
59
67
|
}
|
60
68
|
|
61
|
-
def safeExtGet(prop, fallback) {
|
62
|
-
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
63
|
-
}
|
64
|
-
|
65
69
|
// Check whether Reanimated 2.3 or higher is installed alongside Gesture Handler
|
66
70
|
def shouldUseCommonInterfaceFromReanimated() {
|
67
71
|
def reanimated = rootProject.subprojects.find { it.name == 'react-native-reanimated' }
|
@@ -93,6 +97,7 @@ def noMultipleInstancesAssertion() {
|
|
93
97
|
Set<File> files = fileTree(rootDir.parent) {
|
94
98
|
include "node_modules/**/react-native-gesture-handler/package.json"
|
95
99
|
exclude "**/.yarn/**"
|
100
|
+
exclude "**/.pnpm/**"
|
96
101
|
}.files
|
97
102
|
|
98
103
|
if (files.size() > 1) {
|
@@ -102,7 +107,13 @@ def noMultipleInstancesAssertion() {
|
|
102
107
|
}
|
103
108
|
}
|
104
109
|
|
105
|
-
def REACT_NATIVE_DIR =
|
110
|
+
def REACT_NATIVE_DIR = resolveReactNativeDirectory()
|
111
|
+
|
112
|
+
def reactProperties = new Properties()
|
113
|
+
file("$REACT_NATIVE_DIR/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
|
114
|
+
|
115
|
+
def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME")
|
116
|
+
def REACT_NATIVE_MINOR_VERSION = REACT_NATIVE_VERSION.startsWith("0.0.0-") ? 1000 : REACT_NATIVE_VERSION.split("\\.")[1].toInteger()
|
106
117
|
|
107
118
|
def assertionTask = task assertNoMultipleInstances {
|
108
119
|
onlyIf { shouldAssertNoMultipleInstances() }
|
@@ -131,17 +142,25 @@ android {
|
|
131
142
|
ndkVersion rootProject.ext.ndkVersion
|
132
143
|
}
|
133
144
|
|
145
|
+
if (REACT_NATIVE_MINOR_VERSION >= 71) {
|
146
|
+
buildFeatures {
|
147
|
+
prefab true
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
134
151
|
defaultConfig {
|
135
152
|
minSdkVersion safeExtGet('minSdkVersion', 16)
|
136
153
|
targetSdkVersion safeExtGet('targetSdkVersion', 28)
|
137
154
|
versionCode 1
|
138
155
|
versionName "1.0"
|
139
156
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
157
|
+
buildConfigField "int", "REACT_NATIVE_MINOR_VERSION", REACT_NATIVE_MINOR_VERSION.toString()
|
158
|
+
|
140
159
|
if (isNewArchitectureEnabled()) {
|
141
160
|
var appProject = rootProject.allprojects.find {it.plugins.hasPlugin('com.android.application')}
|
142
161
|
externalNativeBuild {
|
143
162
|
cmake {
|
144
|
-
cppFlags "-O2 -frtti -fexceptions -Wall -
|
163
|
+
cppFlags "-O2", "-frtti", "-fexceptions", "-Wall", "-Werror", "-std=c++17"
|
145
164
|
arguments "-DAPP_BUILD_DIR=${appProject.buildDir}",
|
146
165
|
"-DREACT_NATIVE_DIR=${REACT_NATIVE_DIR}",
|
147
166
|
"-DANDROID_STL=c++_shared"
|
@@ -198,10 +217,10 @@ def kotlin_version = safeExtGet('kotlinVersion', project.properties['RNGH_kotlin
|
|
198
217
|
|
199
218
|
dependencies {
|
200
219
|
//noinspection GradleDynamicVersion
|
201
|
-
if (
|
202
|
-
implementation
|
220
|
+
if (REACT_NATIVE_MINOR_VERSION >= 71) {
|
221
|
+
implementation "com.facebook.react:react-android" // version substituted by RNGP
|
203
222
|
} else {
|
204
|
-
implementation 'com.facebook.react:react-native:+'
|
223
|
+
implementation 'com.facebook.react:react-native:+' // from node_modules
|
205
224
|
}
|
206
225
|
|
207
226
|
if (shouldUseCommonInterfaceFromReanimated()) {
|
@@ -215,20 +234,3 @@ dependencies {
|
|
215
234
|
implementation "androidx.core:core-ktx:1.6.0"
|
216
235
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
217
236
|
}
|
218
|
-
|
219
|
-
if (isNewArchitectureEnabled()) {
|
220
|
-
// Resolves "LOCAL_SRC_FILES points to a missing file, Check that libfb.so exists or that its path is correct".
|
221
|
-
tasks.whenTaskAdded { task ->
|
222
|
-
if (task.name.contains("configureCMakeDebug")) {
|
223
|
-
rootProject.getTasksByName("packageReactNdkDebugLibs", true).forEach {
|
224
|
-
task.dependsOn(it)
|
225
|
-
}
|
226
|
-
}
|
227
|
-
// We want to add a dependency for both configureCMakeRelease and configureCMakeRelWithDebInfo
|
228
|
-
if (task.name.contains("configureCMakeRel")) {
|
229
|
-
rootProject.getTasksByName("packageReactNdkReleaseLibs", true).forEach {
|
230
|
-
task.dependsOn(it)
|
231
|
-
}
|
232
|
-
}
|
233
|
-
}
|
234
|
-
}
|
@@ -331,6 +331,7 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager<ButtonViewGroup>(), R
|
|
331
331
|
// don't preform click when a child button is pressed (mainly to prevent sound effect of
|
332
332
|
// a parent button from playing)
|
333
333
|
return if (!isChildTouched() && soundResponder == this) {
|
334
|
+
tryFreeingResponder()
|
334
335
|
soundResponder = null
|
335
336
|
super.performClick()
|
336
337
|
} else {
|
@@ -16,13 +16,23 @@ import com.swmansion.gesturehandler.core.GestureHandler
|
|
16
16
|
class RNGestureHandlerEvent private constructor() : Event<RNGestureHandlerEvent>() {
|
17
17
|
private var extraData: WritableMap? = null
|
18
18
|
private var coalescingKey: Short = 0
|
19
|
+
|
20
|
+
// On the new architecture, native animated expects event names prefixed with `top` instead of `on`,
|
21
|
+
// since we know when the native animated node is the target of the event we can use the different
|
22
|
+
// event name where appropriate.
|
23
|
+
// TODO: This is a workaround not as solution, but doing this properly would require a total overhaul of
|
24
|
+
// how GH sends events (which needs to be done, but maybe wait until the RN's apis stop changing)
|
25
|
+
private var useTopPrefixedName: Boolean = false
|
26
|
+
|
19
27
|
private fun <T : GestureHandler<T>> init(
|
20
28
|
handler: T,
|
21
29
|
dataExtractor: RNGestureHandlerEventDataExtractor<T>?,
|
30
|
+
useNativeAnimatedName: Boolean
|
22
31
|
) {
|
23
32
|
super.init(handler.view!!.id)
|
24
33
|
extraData = createEventData(handler, dataExtractor)
|
25
34
|
coalescingKey = handler.eventCoalescingKey
|
35
|
+
this.useTopPrefixedName = useNativeAnimatedName
|
26
36
|
}
|
27
37
|
|
28
38
|
override fun onDispose() {
|
@@ -30,7 +40,7 @@ class RNGestureHandlerEvent private constructor() : Event<RNGestureHandlerEvent>
|
|
30
40
|
EVENTS_POOL.release(this)
|
31
41
|
}
|
32
42
|
|
33
|
-
override fun getEventName() = EVENT_NAME
|
43
|
+
override fun getEventName() = if (useTopPrefixedName) NATIVE_ANIMATED_EVENT_NAME else EVENT_NAME
|
34
44
|
|
35
45
|
override fun canCoalesce() = true
|
36
46
|
|
@@ -42,15 +52,17 @@ class RNGestureHandlerEvent private constructor() : Event<RNGestureHandlerEvent>
|
|
42
52
|
|
43
53
|
companion object {
|
44
54
|
const val EVENT_NAME = "onGestureHandlerEvent"
|
55
|
+
const val NATIVE_ANIMATED_EVENT_NAME = "topGestureHandlerEvent"
|
45
56
|
private const val TOUCH_EVENTS_POOL_SIZE = 7 // magic
|
46
57
|
private val EVENTS_POOL = Pools.SynchronizedPool<RNGestureHandlerEvent>(TOUCH_EVENTS_POOL_SIZE)
|
47
58
|
|
48
59
|
fun <T : GestureHandler<T>> obtain(
|
49
60
|
handler: T,
|
50
61
|
dataExtractor: RNGestureHandlerEventDataExtractor<T>?,
|
62
|
+
useTopPrefixedName: Boolean = false
|
51
63
|
): RNGestureHandlerEvent =
|
52
64
|
(EVENTS_POOL.acquire() ?: RNGestureHandlerEvent()).apply {
|
53
|
-
init(handler, dataExtractor)
|
65
|
+
init(handler, dataExtractor, useTopPrefixedName)
|
54
66
|
}
|
55
67
|
|
56
68
|
fun <T : GestureHandler<T>> createEventData(
|
@@ -538,7 +538,11 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) :
|
|
538
538
|
sendEventForReanimated(event)
|
539
539
|
} else if (handler.actionType == GestureHandler.ACTION_TYPE_NATIVE_ANIMATED_EVENT) {
|
540
540
|
// Animated with useNativeDriver: true
|
541
|
-
val event = RNGestureHandlerEvent.obtain(
|
541
|
+
val event = RNGestureHandlerEvent.obtain(
|
542
|
+
handler,
|
543
|
+
handlerFactory,
|
544
|
+
useTopPrefixedName = BuildConfig.REACT_NATIVE_MINOR_VERSION >= 71
|
545
|
+
)
|
542
546
|
sendEventForNativeAnimatedEvent(event)
|
543
547
|
} else if (handler.actionType == GestureHandler.ACTION_TYPE_JS_FUNCTION_OLD_API) {
|
544
548
|
// JS function, Animated.event with useNativeDriver: false using old API
|
@@ -3,57 +3,23 @@ cmake_minimum_required(VERSION 3.9.0)
|
|
3
3
|
|
4
4
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
5
5
|
set(CMAKE_CXX_STANDARD 17)
|
6
|
-
|
6
|
+
|
7
|
+
set(REACT_ANDROID_DIR "${REACT_NATIVE_DIR}/ReactAndroid")
|
8
|
+
|
9
|
+
include(${REACT_ANDROID_DIR}/cmake-utils/folly-flags.cmake)
|
10
|
+
add_compile_options(${folly_FLAGS})
|
7
11
|
|
8
12
|
add_library(gesturehandler
|
9
13
|
SHARED
|
10
14
|
cpp-adapter.cpp
|
11
15
|
)
|
12
16
|
|
13
|
-
|
14
|
-
set(REACT_COMMON_DIR "${REACT_NATIVE_DIR}/ReactCommon")
|
15
|
-
set(REACT_NDK_EXPORT_DIR "${APP_BUILD_DIR}/react-ndk/exported")
|
16
|
-
|
17
|
-
# copied from react-native/ReactAndroid/cmake-utils/Android-prebuilt.cmake
|
18
|
-
|
19
|
-
## jsi
|
20
|
-
add_library(jsi SHARED IMPORTED GLOBAL)
|
21
|
-
set_target_properties(jsi
|
22
|
-
PROPERTIES
|
23
|
-
IMPORTED_LOCATION
|
24
|
-
${REACT_NDK_EXPORT_DIR}/${ANDROID_ABI}/libjsi.so)
|
25
|
-
target_include_directories(jsi INTERFACE ${REACT_COMMON_DIR}/jsi)
|
26
|
-
|
27
|
-
## react_render_core
|
28
|
-
add_library(react_render_core SHARED IMPORTED GLOBAL)
|
29
|
-
set_target_properties(react_render_core
|
30
|
-
PROPERTIES
|
31
|
-
IMPORTED_LOCATION
|
32
|
-
${REACT_NDK_EXPORT_DIR}/${ANDROID_ABI}/libreact_render_core.so)
|
33
|
-
target_include_directories(react_render_core
|
34
|
-
INTERFACE
|
35
|
-
${REACT_COMMON_DIR}
|
36
|
-
${REACT_COMMON_DIR}/react/renderer/core)
|
37
|
-
|
38
|
-
## react_render_uimanager
|
39
|
-
add_library(react_render_uimanager SHARED IMPORTED GLOBAL)
|
40
|
-
set_target_properties(react_render_uimanager
|
41
|
-
PROPERTIES
|
42
|
-
IMPORTED_LOCATION
|
43
|
-
${REACT_NDK_EXPORT_DIR}/${ANDROID_ABI}/libreact_render_uimanager.so)
|
44
|
-
target_include_directories(react_render_uimanager INTERFACE ${REACT_COMMON_DIR}/react/renderer/uimanager)
|
45
|
-
|
46
|
-
target_include_directories(
|
47
|
-
gesturehandler
|
48
|
-
PRIVATE
|
49
|
-
"${REACT_ANDROID_DIR}/build/third-party-ndk/boost/boost_1_76_0"
|
50
|
-
"${REACT_ANDROID_DIR}/build/third-party-ndk/double-conversion"
|
51
|
-
"${REACT_ANDROID_DIR}/build/third-party-ndk/folly"
|
52
|
-
)
|
17
|
+
find_package(ReactAndroid REQUIRED CONFIG)
|
53
18
|
|
54
19
|
target_link_libraries(
|
55
20
|
gesturehandler
|
56
|
-
|
57
|
-
react_render_uimanager
|
58
|
-
|
21
|
+
ReactAndroid::react_render_core
|
22
|
+
ReactAndroid::react_render_uimanager
|
23
|
+
ReactAndroid::jsi
|
24
|
+
ReactAndroid::react_nativemodule_core
|
59
25
|
)
|
@@ -6,8 +6,7 @@
|
|
6
6
|
using namespace facebook;
|
7
7
|
using namespace react;
|
8
8
|
|
9
|
-
void decorateRuntime(jsi::Runtime &runtime)
|
10
|
-
{
|
9
|
+
void decorateRuntime(jsi::Runtime &runtime) {
|
11
10
|
auto isFormsStackingContext = jsi::Function::createFromHostFunction(
|
12
11
|
runtime,
|
13
12
|
jsi::PropNameID::forAscii(runtime, "isFormsStackingContext"),
|
@@ -15,27 +14,31 @@ void decorateRuntime(jsi::Runtime &runtime)
|
|
15
14
|
[](jsi::Runtime &runtime,
|
16
15
|
const jsi::Value &thisValue,
|
17
16
|
const jsi::Value *arguments,
|
18
|
-
size_t count) -> jsi::Value
|
19
|
-
|
20
|
-
if (!arguments[0].isObject())
|
21
|
-
{
|
17
|
+
size_t count) -> jsi::Value {
|
18
|
+
if (!arguments[0].isObject()) {
|
22
19
|
return jsi::Value::null();
|
23
20
|
}
|
24
21
|
|
25
|
-
auto shadowNode = arguments[0]
|
26
|
-
|
22
|
+
auto shadowNode = arguments[0]
|
23
|
+
.asObject(runtime)
|
24
|
+
.getHostObject<ShadowNodeWrapper>(runtime)
|
25
|
+
->shadowNode;
|
26
|
+
bool isFormsStackingContext = shadowNode->getTraits().check(
|
27
|
+
ShadowNodeTraits::FormsStackingContext);
|
27
28
|
|
28
29
|
return jsi::Value(isFormsStackingContext);
|
29
30
|
});
|
30
|
-
runtime.global().setProperty(
|
31
|
+
runtime.global().setProperty(
|
32
|
+
runtime, "isFormsStackingContext", std::move(isFormsStackingContext));
|
31
33
|
}
|
32
34
|
|
33
35
|
extern "C" JNIEXPORT void JNICALL
|
34
|
-
Java_com_swmansion_gesturehandler_react_RNGestureHandlerModule_decorateRuntime(
|
35
|
-
|
36
|
+
Java_com_swmansion_gesturehandler_react_RNGestureHandlerModule_decorateRuntime(
|
37
|
+
JNIEnv *env,
|
38
|
+
jobject clazz,
|
39
|
+
jlong jsiPtr) {
|
36
40
|
jsi::Runtime *runtime = reinterpret_cast<jsi::Runtime *>(jsiPtr);
|
37
|
-
if (runtime)
|
38
|
-
{
|
41
|
+
if (runtime) {
|
39
42
|
decorateRuntime(*runtime);
|
40
43
|
}
|
41
44
|
}
|
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
@interface RNBetterSwipeGestureRecognizer : UISwipeGestureRecognizer
|
4
4
|
|
5
|
-
- (id)initWithGestureHandler:(RNGestureHandler*)gestureHandler;
|
5
|
+
- (id)initWithGestureHandler:(RNGestureHandler *)gestureHandler;
|
6
6
|
|
7
7
|
@end
|
8
8
|
|
9
9
|
@implementation RNBetterSwipeGestureRecognizer {
|
10
|
-
__weak RNGestureHandler*
|
10
|
+
__weak RNGestureHandler *_gestureHandler;
|
11
11
|
CGPoint _lastPoint; // location of the most recently updated touch, relative to the view
|
12
12
|
bool _hasBegan; // whether the `BEGAN` event has been sent
|
13
13
|
}
|
@@ -27,6 +27,7 @@
|
|
27
27
|
_lastPoint = [[[touches allObjects] objectAtIndex:0] locationInView:_gestureHandler.recognizer.view];
|
28
28
|
[_gestureHandler reset];
|
29
29
|
[super touchesBegan:touches withEvent:event];
|
30
|
+
[_gestureHandler.pointerTracker touchesBegan:touches withEvent:event];
|
30
31
|
|
31
32
|
// self.numberOfTouches doesn't work for this because in case than one finger is required,
|
32
33
|
// when holding one finger on the screen and tapping with the second one, numberOfTouches is equal
|
@@ -35,8 +36,6 @@
|
|
35
36
|
[self triggerAction];
|
36
37
|
_hasBegan = YES;
|
37
38
|
}
|
38
|
-
|
39
|
-
[_gestureHandler.pointerTracker touchesBegan:touches withEvent:event];
|
40
39
|
}
|
41
40
|
|
42
41
|
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
@@ -73,7 +72,8 @@
|
|
73
72
|
[super reset];
|
74
73
|
}
|
75
74
|
|
76
|
-
- (CGPoint)getLastLocation
|
75
|
+
- (CGPoint)getLastLocation
|
76
|
+
{
|
77
77
|
// I think keeping the location of only one touch is enough since it would be used to determine the direction
|
78
78
|
// of the movement, and if it's wrong the recognizer fails anyway.
|
79
79
|
// In case the location of all touches is required, touch events are the way to go
|
@@ -103,48 +103,50 @@
|
|
103
103
|
|
104
104
|
- (void)configure:(NSDictionary *)config
|
105
105
|
{
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
106
|
+
[super configure:config];
|
107
|
+
UISwipeGestureRecognizer *recognizer = (UISwipeGestureRecognizer *)_recognizer;
|
108
|
+
|
109
|
+
id prop = config[@"direction"];
|
110
|
+
if (prop != nil) {
|
111
|
+
recognizer.direction = [RCTConvert NSInteger:prop];
|
112
|
+
}
|
113
|
+
|
114
114
|
#if !TARGET_OS_TV
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
115
|
+
prop = config[@"numberOfPointers"];
|
116
|
+
if (prop != nil) {
|
117
|
+
recognizer.numberOfTouchesRequired = [RCTConvert NSInteger:prop];
|
118
|
+
}
|
119
119
|
#endif
|
120
120
|
}
|
121
121
|
|
122
122
|
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
|
123
123
|
{
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
124
|
+
RNGestureHandlerState savedState = _lastState;
|
125
|
+
BOOL shouldBegin = [super gestureRecognizerShouldBegin:gestureRecognizer];
|
126
|
+
_lastState = savedState;
|
127
|
+
|
128
|
+
return shouldBegin;
|
129
129
|
}
|
130
130
|
|
131
131
|
- (RNGestureHandlerEventExtraData *)eventExtraData:(id)_recognizer
|
132
132
|
{
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
133
|
+
// For some weird reason [recognizer locationInView:recognizer.view.window] returns (0, 0).
|
134
|
+
// To calculate the correct absolute position, first calculate the absolute position of the
|
135
|
+
// view inside the root view controller (https://stackoverflow.com/a/7448573) and then
|
136
|
+
// add the relative touch position to it.
|
137
|
+
|
138
|
+
RNBetterSwipeGestureRecognizer *recognizer = (RNBetterSwipeGestureRecognizer *)_recognizer;
|
139
|
+
|
140
|
+
CGPoint viewAbsolutePosition =
|
141
|
+
[recognizer.view convertPoint:recognizer.view.bounds.origin
|
142
|
+
toView:[UIApplication sharedApplication].keyWindow.rootViewController.view];
|
143
|
+
CGPoint locationInView = [recognizer getLastLocation];
|
144
|
+
|
145
|
+
return [RNGestureHandlerEventExtraData
|
146
|
+
forPosition:locationInView
|
147
|
+
withAbsolutePosition:CGPointMake(
|
148
|
+
viewAbsolutePosition.x + locationInView.x, viewAbsolutePosition.y + locationInView.y)
|
149
|
+
withNumberOfTouches:recognizer.numberOfTouches];
|
147
150
|
}
|
148
151
|
|
149
152
|
@end
|
150
|
-
|
@@ -11,7 +11,7 @@
|
|
11
11
|
@property (nonatomic) CGFloat force;
|
12
12
|
@property (nonatomic) BOOL feedbackOnActivation;
|
13
13
|
|
14
|
-
- (id)initWithGestureHandler:(RNGestureHandler*)gestureHandler;
|
14
|
+
- (id)initWithGestureHandler:(RNGestureHandler *)gestureHandler;
|
15
15
|
|
16
16
|
@end
|
17
17
|
|
@@ -25,7 +25,7 @@ static const CGFloat defaultMinForce = 0.2;
|
|
25
25
|
static const CGFloat defaultMaxForce = NAN;
|
26
26
|
static const BOOL defaultFeedbackOnActivation = NO;
|
27
27
|
|
28
|
-
- (id)initWithGestureHandler:(RNGestureHandler*)gestureHandler
|
28
|
+
- (id)initWithGestureHandler:(RNGestureHandler *)gestureHandler
|
29
29
|
{
|
30
30
|
if ((self = [super initWithTarget:gestureHandler action:@selector(handleGesture:)])) {
|
31
31
|
_gestureHandler = gestureHandler;
|
@@ -45,7 +45,7 @@ static const BOOL defaultFeedbackOnActivation = NO;
|
|
45
45
|
}
|
46
46
|
[super touchesBegan:touches withEvent:event];
|
47
47
|
[_gestureHandler.pointerTracker touchesBegan:touches withEvent:event];
|
48
|
-
|
48
|
+
|
49
49
|
_firstTouch = [touches anyObject];
|
50
50
|
[self handleForceWithTouches:touches];
|
51
51
|
self.state = UIGestureRecognizerStatePossible;
|
@@ -59,25 +59,27 @@ static const BOOL defaultFeedbackOnActivation = NO;
|
|
59
59
|
}
|
60
60
|
[super touchesMoved:touches withEvent:event];
|
61
61
|
[_gestureHandler.pointerTracker touchesMoved:touches withEvent:event];
|
62
|
-
|
62
|
+
|
63
63
|
[self handleForceWithTouches:touches];
|
64
|
-
|
64
|
+
|
65
65
|
if ([self shouldFail]) {
|
66
66
|
self.state = UIGestureRecognizerStateFailed;
|
67
67
|
return;
|
68
68
|
}
|
69
|
-
|
69
|
+
|
70
70
|
if (self.state == UIGestureRecognizerStatePossible && [self shouldActivate]) {
|
71
71
|
[self performFeedbackIfRequired];
|
72
72
|
self.state = UIGestureRecognizerStateBegan;
|
73
73
|
}
|
74
74
|
}
|
75
75
|
|
76
|
-
- (BOOL)shouldActivate
|
76
|
+
- (BOOL)shouldActivate
|
77
|
+
{
|
77
78
|
return (_force >= _minForce);
|
78
79
|
}
|
79
80
|
|
80
|
-
- (BOOL)shouldFail
|
81
|
+
- (BOOL)shouldFail
|
82
|
+
{
|
81
83
|
return TEST_MAX_IF_NOT_NAN(_force, _maxForce);
|
82
84
|
}
|
83
85
|
|
@@ -113,11 +115,13 @@ static const BOOL defaultFeedbackOnActivation = NO;
|
|
113
115
|
[_gestureHandler.pointerTracker touchesCancelled:touches withEvent:event];
|
114
116
|
}
|
115
117
|
|
116
|
-
- (void)handleForceWithTouches:(NSSet<UITouch *> *)touches
|
118
|
+
- (void)handleForceWithTouches:(NSSet<UITouch *> *)touches
|
119
|
+
{
|
117
120
|
_force = _firstTouch.force / _firstTouch.maximumPossibleForce;
|
118
121
|
}
|
119
122
|
|
120
|
-
- (void)reset
|
123
|
+
- (void)reset
|
124
|
+
{
|
121
125
|
[_gestureHandler.pointerTracker reset];
|
122
126
|
[super reset];
|
123
127
|
_force = 0;
|
@@ -140,7 +144,7 @@ static const BOOL defaultFeedbackOnActivation = NO;
|
|
140
144
|
{
|
141
145
|
[super resetConfig];
|
142
146
|
RNForceTouchGestureRecognizer *recognizer = (RNForceTouchGestureRecognizer *)_recognizer;
|
143
|
-
|
147
|
+
|
144
148
|
recognizer.feedbackOnActivation = defaultFeedbackOnActivation;
|
145
149
|
recognizer.maxForce = defaultMaxForce;
|
146
150
|
recognizer.minForce = defaultMinForce;
|
@@ -162,12 +166,10 @@ static const BOOL defaultFeedbackOnActivation = NO;
|
|
162
166
|
|
163
167
|
- (RNGestureHandlerEventExtraData *)eventExtraData:(RNForceTouchGestureRecognizer *)recognizer
|
164
168
|
{
|
165
|
-
return [RNGestureHandlerEventExtraData
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
withNumberOfTouches:recognizer.numberOfTouches];
|
169
|
+
return [RNGestureHandlerEventExtraData forForce:recognizer.force
|
170
|
+
forPosition:[recognizer locationInView:recognizer.view]
|
171
|
+
withAbsolutePosition:[recognizer locationInView:recognizer.view.window]
|
172
|
+
withNumberOfTouches:recognizer.numberOfTouches];
|
170
173
|
}
|
171
174
|
|
172
175
|
@end
|
173
|
-
|