From bf7e2a85d08b96aacc97b56f535d49f9d853044f Mon Sep 17 00:00:00 2001 From: James Ide Date: Fri, 24 Jul 2015 14:22:31 -0700 Subject: [PATCH] [Navigator] Vertically hide disabled scenes and use pointerEvents="none" Summary: Hides disabled scenes using `top` instead of `left`, which fixes a bug with the native UITabBar. When the UITabBar's width is zeroed because the scene has `left: SCREEN_WIDTH, right: 0` applied, this triggers a bug with the kerning of the tab titles. Instead, zeroing the height by setting `top: SCREEN_HEIGHT` avoids the bug. Also applies `pointerEvents="none"` to disabled scenes so that views in the off-screen scenes definitely don't receive touches, which was occurring before. Fixes #1401, fixes #2011 Closes https://github.com/facebook/react-native/pull/2104 Github Author: James Ide --- .../CustomComponents/Navigator/Navigator.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Libraries/CustomComponents/Navigator/Navigator.js b/Libraries/CustomComponents/Navigator/Navigator.js index 743d914a709..6589e7d780d 100644 --- a/Libraries/CustomComponents/Navigator/Navigator.js +++ b/Libraries/CustomComponents/Navigator/Navigator.js @@ -56,8 +56,9 @@ var PropTypes = React.PropTypes; var SCREEN_WIDTH = Dimensions.get('window').width; var SCREEN_HEIGHT = Dimensions.get('window').height; var SCENE_DISABLED_NATIVE_PROPS = { + pointerEvents: 'none', style: { - left: SCREEN_WIDTH, + top: SCREEN_HEIGHT, opacity: 0, }, }; @@ -107,7 +108,7 @@ var styles = StyleSheet.create({ top: 0, }, disabledScene: { - left: SCREEN_WIDTH, + top: SCREEN_HEIGHT, }, transitioner: { flex: 1, @@ -529,15 +530,18 @@ var Navigator = React.createClass({ _enableScene: function(sceneIndex) { // First, determine what the defined styles are for scenes in this navigator var sceneStyle = flattenStyle([styles.baseScene, this.props.sceneStyle]); - // Then restore the left value for this scene + // Then restore the pointer events and top value for this scene var enabledSceneNativeProps = { - left: sceneStyle.left, + pointerEvents: 'auto', + style: { + top: sceneStyle.top, + }, }; if (sceneIndex !== this.state.transitionFromIndex && sceneIndex !== this.state.presentedIndex) { // If we are not in a transition from this index, make sure opacity is 0 // to prevent the enabled scene from flashing over the presented scene - enabledSceneNativeProps.opacity = 0; + enabledSceneNativeProps.style.opacity = 0; } this.refs['scene_' + sceneIndex] && this.refs['scene_' + sceneIndex].setNativeProps(enabledSceneNativeProps); @@ -1021,8 +1025,10 @@ var Navigator = React.createClass({ _renderScene: function(route, i) { var disabledSceneStyle = null; + var disabledScenePointerEvents = 'auto'; if (i !== this.state.presentedIndex) { disabledSceneStyle = styles.disabledScene; + disabledScenePointerEvents = 'none'; } return ( { return (this.state.transitionFromIndex != null) || (this.state.transitionFromIndex != null); }} + pointerEvents={disabledScenePointerEvents} style={[styles.baseScene, this.props.sceneStyle, disabledSceneStyle]}> {this.props.renderScene( route,