Closed bleonard closed 9 years ago
I would be ok with adding acceptTap
and allowPan
props, or something along those lines. I am a little concerned about prop bloat though, especially as we look to add in more advanced features like multiple drawers.
Another option would be a toggleMode(s)
prop that is an array of acceptable toggle methods ['pan', 'press', 'doublePress'].
Need to think about this more, but I will probably add the first two props to solve your use case for now, and take a hard look at refactoring the props in 2.0.
Sweet. Thanks. Let me know if you want me to test it out.
try out v1.1.4
new props are acceptTap
and acceptPan
(for consistency with acceptDoubleTap). You probably want to set them to true and false respectively, as well as set panCloseMask
to equal your open offset.
I used v1.2.1 - should that have worked? It did seem to accept tap. Thanks for responding so quickly!
Here is my current setup:
<Drawer
ref="drawer"
acceptTap={true} // tap to open
acceptPan={false} // have to hit button
openDrawerOffset={showWhenOpenPercent} // percent of screen to leave open (can also be pixels)
panCloseMask={showWhenOpenPercent} // allow slide it closed for now TODO: tap anywhere on it
panOpenMask={0.0} // zero so no taps will work TODO: allow boolean in real project
content={<Sidebar selectedRoute={parsed.route} />}
>
I found that acceptTap
worked as expected to close the drawer.
I'm not sure acceptPan
worked, though. I figured that would allow me to not have to set panOpenMask
to zero, so I unset that. However, that configuration opened the drawer with any click in the left-ish side of the screen. Putting back to zero gives me the behavior I want, but I thought you'd want to know.
One thing I noticed is that the tap to close the drawer continues to propogate to the children. For example, if the app is showing the drawer and there is a button on the "main" page, tapping anywhere on the page should close the drawer. That works as expected. However, if that tap happens to be on the button, it still executes that. On our current iOS implementation, we found that to be a problem as people hit stuff accidentally a lot. Is there a stopProgagation()
call to make somewhere?
Yes, allowing false for panOpenMask is probably a good idea. That said setting it to 0 (as in your example) was my intended solution. acceptTap
refers to both tap to open and tap to close.
Propagation starts form the child and bubbles up. Another person had a similar request with respect to blocking pan on children. I will take a look...
Ok, I have a solution, although it is not super pretty:
Basically the strategy is to mask your content with a pan responder when the drawer is open. I got it working using roughly the following code:
<Drawer
ref="drawer"
onOpen={() => {
this.setState({disableGestures : true})
}}
onClose={() => {
this.setState({disableGestures : false})
}}
acceptTap={true} // tap to open
acceptPan={false} // have to hit button
openDrawerOffset={showWhenOpenPercent}
panCloseMask={showWhenOpenPercent}
panOpenMask={0.0} // zero so no taps will work TODO: allow boolean in real project
content={<Sidebar selectedRoute={parsed.route} />}
>
<Main disableGestures={this.state.disableGestures} />
</Drawer>
//...
var Main = React.createClass({
render(){
return (
<View>
<Content />
{this.props.disableGestures ? <CaptureGestures /> : null}
</View>
}
})
var React = require('react-native')
var {NativeModules, StyleSheet, PanResponder, View} = React
var deviceScreen = NativeModules.UIManager.Dimensions.window
module.exports = React.createClass({
componentWillMount: function() {
this._panGesture = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => { return false },
onStartShouldSetPanResponderCapture: (evt, gestureState) => { return false },
onMoveShouldSetPanResponder: (evt, gestureState) => { return false },
onMoveShouldSetPanResponderCapture: (evt, gestureState) => { return false },
});
},
render () {
var style = {
position: 'absolute',
top: 0,
left: 0,
width: this.props.width || deviceScreen.width,
height: deviceScreen.height,
backgroundColor: 'transparent'
}
return (
<View style={style} {...this._panGesture.panHandlers} />
);
}
});
It will probably take some massaging to work with your exact use case. I played around with adding another prop to handle this case, but I do not yet have a generic solution I am happy enough with.
Let me know if that works for you.
Note: in investigating I found a bug in the shouldComponentUpdate code, so you will need to update to the latest
It works! Thanks for your help.
The spec on the drawer I'm supposed to build is:
1) button to open the drawer 2) no sliding to open the drawer - only the button 3) opens most of the way but "main" content can still be seen on the right 4) tap on what is seen on the right to close it 5) no sliding to close
I am able to accomplish most of these with the current code:
1) call
drawer.open()
when button is hit 2) setpanOpenMask={0.0}
to prevent sliding 3) setopenDrawerOffset={0.15}
to show 15% of it 4) does not seem possible 5) setpanCloseMask={0.0}
to prevent sliding2 and 5 are a little hacky so I'd love it if there was a boolean
slides={false}
. This might also allow you to completely stop all the pan listening and recording. I'm not sure the performance impact on that.However, 4 does not seem to work. There has to be some panning. So the feature request is to be able to tap the "main" content to be able to close it. Ideally it would also prevent it from interacting with the main content.
Thanks.