Description
- Review the documentation: https://facebook.github.io/react-native
- Search for existing issues: https://github.com/facebook/react-native/issues
- Use the latest React Native version: https://github.com/facebook/react-native/releases
- Run
react-native info
in your terminal and paste its contents under "Environment" - Let us know how to reproduce the issue. Include a code sample, share a project, or
share an app that reproduces the issue using https://snack.expo.io/
Environment
React Native Environment Info:
System:
OS: macOS High Sierra 10.13.5
CPU: x64 Intel(R) Core(TM) i7-6660U CPU @ 2.40GHz
Memory: 4.38 GB / 16.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 10.5.0 - /usr/local/bin/node
Yarn: 1.7.0 - ~/.yarn/bin/yarn
npm: 6.1.0 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 11.4, macOS 10.13, tvOS 11.4, watchOS 4.3
Android SDK:
Build Tools: 23.0.1, 25.0.0, 25.0.1, 25.0.2, 26.0.0, 26.0.1, 26.0.2, 26.0.3
API Levels: 19, 21, 22, 23, 24, 25, 26
IDEs:
Android Studio: 3.0 AI-171.4443003
Xcode: 9.4.1/9F2000 - /usr/bin/xcodebuild
npmPackages:
react: 16.4.1 => 16.4.1
react-native: 0.56.0 => 0.56.0
npmGlobalPackages:
create-react-native-app: 1.0.0
react-native-cli: 2.0.1
react-native-rename: 2.2.2
Description
The bounds of transformed views, as reported by the inspector or as detected by the Touchable components, do not match what you seen on the screen. The touch area is not correctly transformed with the view.
Screenshot of a { scale: 2 } transform
The real view (scaled) is in pink, the incorrect touchable area is in blue.
Screenshot of a { rotateZ: "-45deg" } transform
The real view (rotated) is in pink, the incorrect touchable area is in blue.
This issue has already been reported in 2016 but has been closed because it was missing reproduction steps. This bug has been here for a long time.
Steps to Reproduce
- Use a real device (I haven't been able to reproduce the bug on emulator, I have on a real Galaxy A5 2017)
UPDATE: See this comment for an emulator reproduction. - Use the inspector to display the view bounds
- See that the reported bounds (blue square) do not match the real view (pink square)
- Without the inspector, press somewhere on the real view where the blue square didn't overlap: the press is not correctly detected. onPressOut is triggered immediately after onPressIn, without onPress being triggered. onPressOut is immediately triggered even if you don't release the touch. Sometimes on the very first press, onPress is logged but it doesn't wait for touch release.
Demo code with on-screen logging
I've included some on-screen logging code to easily see the press events.
This example shows the bug with the scale transform but it can be reproduced with a rotate transform as well.
import React from "react";
import { AppRegistry, View, TouchableOpacity, Text } from "react-native";
let i = 1;
class Demo extends React.Component {
state = {
logs: []
};
log(str) {
this.setState(state => ({
logs: [...state.logs.slice(-5), `${i++} - ${str}`]
}));
}
render() {
return (
<View style={{ flex: 1 }}>
<View style={{
position: "absolute",
top: 100,
left: 100,
height: 100,
width: 100,
transform: [{
scale: 2 // you can also try rotateZ: "-45deg"
}]
}}>
<TouchableOpacity
onPress={() => this.log("pressed")}
onPressIn={() => this.log("pressed in")}
onPressOut={() => this.log("pressed out")}
style={{
flex: 1,
backgroundColor: "pink"
}}
/>
</View>
<View style={{ position: "absolute", bottom: 0, height: 200 }}>
<Text style={{ fontWeight: "bold", fontSize: 20 }}>Logs</Text>
<Text>{this.state.logs.join("\n")}</Text>
</View>
</View>
);
}
}
AppRegistry.registerComponent("Demo", () => Demo);
Minimal example without on-screen logging
import React from "react";
import { AppRegistry, View, TouchableOpacity } from "react-native";
class Demo extends React.Component {
render() {
return (
<View style={{ flex: 1 }}>
<View style={{
position: "absolute",
top: 100,
left: 100,
height: 100,
width: 100,
transform: [{
scale: 2 // you can also try rotateZ: "-45deg"
}]
}}>
<TouchableOpacity
onPress={() => alert("pressed")}
style={{
flex: 1,
backgroundColor: "pink"
}}
/>
</View>
</View>
);
}
}
AppRegistry.registerComponent("Demo", () => Demo);
Expected Behavior
The bounds should match the view even when transformed.
The touch area should match what you see.
Actual Behavior
The bounds are not correctly transformed.
The touch area is not correctly transformed and press behaviour is broken where the real view and the incorrect bounds do not overlap.