I'm trying to fix an issue in a library (https://github.com/dancormier/react-native-swipeout/issues/38) that appears to be broken on the 6s and 6s plus. The pan responder doesn't appear to allow touchable children to be pressed.
The library works on older devices with the same version of iOS, which makes me think that this has something to do with the new 3d touch hardware.
As noted in the other issue also, the library works in the emulator, but not the actual devices.
+1 – We're also experiencing this problem on new 3d touch phones.
The nested touchable highlights don't react visually to touch, and aren't clickable, but tapping quickly a few times often ends up working.
Could it be related to this iOS9 bug?
https://developer.apple.com/library/prerelease/ios/releasenotes/General/RN-iOSSDK-9.1/#//apple_ref/doc/uid/TP40016570-CH1-DontLinkElementID_25 — "touch pressure changes cause touchesMoved:
to be called"
Is this affecting anyone else? Or is PanResponder not really used often?
I'm worried that our app has become pretty much unusable for anyone with a new iPhone. Would love to find some sort of solution to this.
+1 we are seeing the same thing here! @a2 @nicklockwood ideas?
We had a same problem, fortunately only on a few places so we could easily fix it by checking if dy
/ dx
is not 0 before granting a PanResponder in onMoveShouldSetPanResponder
.
On the bottom of the page @aprilzero linked is written:
Apps should be prepared to receive touch move events with no change in the x/y coordinates.
I guess from now on we will just have to check for actual movement before granting.
@meznaric 👏 thanks! That seems to fix the problem for us.
Same issue here - but with Navigator. A button close to the edge of the screen stops working. I've tried setting 'gestures: null' the routes sceneConfig, but this actually stops taps from working at all (only force touch works).
I tried the Navigator and react-native-swipeout
and everything seemed to work as expected, can any of you guys provide a sample or more detailed repro steps?
My issue is actually different. A button which is normally easy to tap has its tappable area shifted off to its left edge. Kust got an iPhone 6s now and will post more info soon.
I think our flashcards are broken(not tappable) on 6s because of this. This is just a higher level guess will debug today.
I solved my problem: I had a TouchableOpacity with a nested wrapper view, and both the touchable and nested view had been set to position: absolute. I'm not sure yet why this would work on iPhone6 and not 6s - but will debug further and see if I can isolate a test case.
For now, here's a gist with the broken and fixed component:
https://gist.github.com/jsierles/6ea15850dab3c65dceeb
More details:
logging in Touchable.js touchableHandleResponderMove, the touchState for the broken component, when doing a single tap, always looks like this:
2015-10-09 18:29:53.204 [info][tid:com.facebook.React.JavaScript] 'RESPONDER_ACTIVE_PRESS_IN'
2015-10-09 18:29:53.222 [info][tid:com.facebook.React.JavaScript] 'RESPONDER_ACTIVE_PRESS_OUT'
The fixed component only sets RESPONDER_ACTIVE_PRESS_IN.
I haven't had time to fully debug, but here's an example TouchableOpacity element that works on the iPhone6 but not 6s. You have to use a real device, not the simulator, to reproduce. Tapping on the large square fails ~80% of the time.
https://github.com/jsierles/RNiPhone6sTest
I fixed this by removing the redundant 'position: absolute' on the child view.
Maybe this can help get to the bottom of the issue.
I just tried to debug this on 6s(had to buy a new one).
This is definitely a problem with position: absolute
in child views. I have a setup like this:
<TouchableWithoutFeedback>
<View>
<View style={position: absolute} />
<View style={position: absolute} />
</View>
</TouchableWithoutFeedback>
Changing it to this fixes it:
<TouchableWithoutFeedback>
<View>
<View />
<View style={position: absolute} />
</View>
</TouchableWithoutFeedback>
Note: touchesMove
is always called on 6s while it's not always called for iphone < 6.
cc @tadeuzagallo above setup should help debug. It works on simulator, you need a 6s to reproduce it.
My issue was resolved by @meznaric's comment
i just find a not beautiful but convenient way to solve this problem(maxs15/react-native-modalbox#19)
just use onPressIn not onPress in Touchable*.
@meznaric's https://github.com/facebook/react-native/issues/3082#issuecomment-144689910 fixed the issue in my case.
I have side drawer with TouchableOpacity
buttons and this PanResponder
rule fixed the problem on iPhone 6s:
onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
return Math.abs(gestureState.dx) > 5;
},
:+1: :clap:
@neciu it also solved it for me
onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
return gestureState.dx != 0 && gestureState.dy != 0;
},
Worked for me (we are building a music player that drags up), the solution above with > 5
seemed to make the dragging action not sensitive enough.
Worked--thanks everyone!
Ran into this issue on a Note 5 running Android 5.1. Doesn't occur in the emulator but kills all Touchables when running on actual device.
@meznaric and @neciu solution fixed it right up. Thanks!
I'm having a related issue where a Touchable inside a scrollview doesn't receive onPress if any pressure is applied on a 6s screen.
Using React Native version 0.30.0, I wasn't able to get this project working in 0.31.0-rc.1 so not sure if a fix has been merged for that version yet.
The only way to make the button respond is to touch it as lightly and quickly as possible. Otherwise it fails to receive press, even with a relatively normal pressure and velocity.
Should I open a new issue?
@mosesoak We had a similar problem to yours using RN 0.31 and 0.32. Our solution was to use onPressOut
with delayPressOut
. This allows us a small window of time to determine whether or not to go through with the onPress
action. It's super hacky and we're not too happy with it, but it works for now.
Okay I'll check with the team to see if they can use that workaround – thanks!
I was only partly able to resolve this issue in my project by implementing the proposed fix onMoveShouldSetPanResponder
. Instead I was able to get my touchable to work by setting a hitSlop
to it!
Like this
hitSlop={{top: 12, left: 36, bottom: 0, right: 0}}
I also resolved this myself by ensuring that whenever I used hitSlop
I added properties for each direction (top
, bottom
, left
and right
), even if the value is just 0
When I missed a property, I encountered this issue.
I had a similar issue affecting touchables where I had a absolutely positioned view within my pan responder (intended to be a backdrop), it seemed that occasionally the view wouldn't get unmounted correctly and blocked touchables.
I had to change something like this
<View style={styles.container} {...this._panResponder.panHandlers}>
{this.state.isVisible && <Animated.View style={[styles.backdrop, {position:'absolute']}/>}
</View/>
To
<View style={styles.container} {...this._panResponder.panHandlers}>
<Animated.View style={[styles.backdrop, {position:this.state.isVisible?'absolute':'relative'}]}/>
</View/>
I replicated this with both my own pan responder and react-native-drawer-layout which had the same approach (an absolute full screen backdrop)
Why was this issue closed? I think that's a bug of the existing Touchables and it still needs to be taken care of..!
Ok so if anyone needs more info on a workaround for this, see this thread:
http://stackoverflow.com/questions/41983107/how-to-make-a-touchableopacity-or-touchablehighlight-clickable-on-devices-that-s/42069488#42069488
@meznaric,Good suggestion!
In my suitation, i need to set on both function:
onStartShouldSetPanResponderCapture: (evt, gestureState) => {
console.log("onStartShouldSetPanResponderCapture", gestureState.dx,
gestureState.dy);
return gestureState.dx != 0 && gestureState.dy != 0;
},
onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
console.log("onMoveShouldSetPanResponderCapture", gestureState.dx,
gestureState.dy);
return gestureState.dx != 0 && gestureState.dy != 0;
},
But it make touch effect (blur) on start pharse of move touch although it don't init onPress function
@phanngoc thx~
This is still an issue and the proposed solution doesn't always work. Could it be re-opened? It doesn't seem like it should be expected behaviour...
Agreed, I'm seeing it as well.
Re-opening because this seems like a real issue.
Does it also happen on an iPhone 7?
A fix would be appreciated for this, if anybody can figure it out!
@ericvicenti yes this happens on iPhone 7 as well!
Just an FYI – you can test whether this issue is happening in the simulator by clicking and holding on the touchable, moving your mouse away, then moving it back over the touchable. If the touchable appears pressed again (i.e. TouchableOpacity
goes transparent or TouchableHighlight
goes highlighted), you will not have the 3D Touch issue. If it doesn't, you will have this bug.
Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!
If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:
If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.
Strange enough, @spacesuitdiver's fix wasn't working for me until I switched from TouchableWithoutFeedback
to TouchableOpacity
, then it worked..
@meznaric Your hack worked like a charm 🥇
@meznaric thank you 💚Not sure why this issue is closed.
Most helpful comment
Worked for me (we are building a music player that drags up), the solution above with
> 5
seemed to make the dragging action not sensitive enough.