Skip to content

PlatformConstants no longer a member of NativeModules (breaks ForceTouchGestureHandler) #1210

@drewandre

Description

@drewandre

Description

ForceTouchGestureHandler was not working on my iPhone XS Max (claiming it was unavailable on the platform which is untrue) and after digging into it I can see that in PlatformConstants.js, PlatformConstants is no longer a member of react-native's NativeModules export. Because we're querying PlatformConstants.forceTouchAvailable in Gestures.js, this results in <ForceTouchFallback /> being rendered rather than the actual gesture handler.

I wasn't easily able to see which RN version broke this, but since Gestures.js is the only file that imports PlatformConstants.js, I think we could just import { Platform } from 'react-native' here and query Platform.constants.forceTouchAvailable rather than conditionally import NativeModules if on RN v0.60.x, and from Platform if on newer RN versions. That being said, I imagine for future development it's nice to have a centralized PlatformConstants file. I just don't know how the software mansion team would approach this issue while maintaining backwards compatibility.

Screenshots

Steps To Reproduce

Rather than upgrading the entire react-native-gesture-library to support the latest react-native v0.63.3, I just used the reanimated v2 playground repo.

  1. git clone https://github.com/software-mansion-labs/reanimated-2-playground
  2. npm install, pod install
  3. Paste the example code below.
  4. To fix, replace import PlatformConstants from './PlatformConstants'; with import { Platform } from 'react-native'; in node_modules/react-native-gesture-handler/Gestures.js, and change both instances of PlatformConstants && PlatformConstants.forceTouchAvailable with Platform.constants.forceTouchAvailable.

Expected behavior

ForceTouchGestureHandler works as expected on force touch-capable devices running latest react-native versions.

Actual behavior

<ForceTouchFallback /> is rendered on devices that do in fact support a force touch handler.

Snack or minimal code example

Here is a force touch gesture handler example using reanimated v2, though the issue would still be present in reanimated v1:

import Animated, {
  useSharedValue,
  useAnimatedStyle,
  useAnimatedGestureHandler,
} from 'react-native-reanimated';
import { View, StyleSheet } from 'react-native';
import React from 'react';
import { ForceTouchGestureHandler } from 'react-native-gesture-handler';

export default function AnimatedStyleUpdateExample(props) {
  const force = useSharedValue(0);

  const animatedBoxStyles = useAnimatedStyle(() => {
    return {
      transform: [
        { scale: 1 + force.value }
      ]
    };
  });

  const onForceTouchGestureEvent = useAnimatedGestureHandler({
    onStart: (evt) => {
      force.value = evt.force
    },
    onActive: (evt) => {
      force.value = evt.force
    },
    onFinish: () => {
      force.value = 0
    }
  })

  return (
    <View style={styles.container}>
      <ForceTouchGestureHandler
        minForce={0}
        feedbackOnActivation
        onGestureEvent={onForceTouchGestureEvent}>
        <Animated.View style={[styles.box, animatedBoxStyles]} />
      </ForceTouchGestureHandler>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: 'red'
  }
})

Package versions

"react": "16.13.1",
"react-native": "0.63.1",
"react-native-gesture-handler": "^1.6.1",
"react-native-reanimated": "2.0.0-alpha.7",

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions