diff --git a/example/App.tsx b/example/App.tsx index 216f1bb..5003379 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -41,12 +41,9 @@ export default function App() { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: '#fff', - alignItems: 'center', - justifyContent: 'center', }, contentContainerStyle: { - padding: 16, + padding: 24, backgroundColor: '#F3F4F9', }, header: { diff --git a/src/index.tsx b/src/index.tsx index 8eef795..26569c9 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,10 +4,12 @@ import { Dimensions, FlatList, FlatListProps, + Platform, ScrollViewProps, SectionList, SectionListProps, StyleSheet, + View, } from 'react-native'; import { NativeViewGestureHandler, @@ -16,6 +18,7 @@ import { PanGestureHandlerStateChangeEvent, ScrollView, State, + TapGestureHandler, } from 'react-native-gesture-handler'; import { Assign } from 'utility-types'; @@ -88,6 +91,8 @@ export class ScrollBottomSheet extends Component> { private drawerContentRef = React.createRef(); private scrollComponentRef = React.createRef(); + private iOSMasterDrawer = React.createRef(); + /** * Reference to FlatList, ScrollView or SectionList in order to execute its imperative methods. */ @@ -240,6 +245,13 @@ export class ScrollBottomSheet extends Component> { onHeaderHandlerStateChange: PanGestureHandlerProperties['onHandlerStateChange'] = ({ nativeEvent, }) => { + if (nativeEvent.state === State.BEGAN && Platform.OS === 'ios') { + // @ts-ignore + this.contentComponentRef.current?._component?.setNativeProps({ + decelerationRate: 0, + disableIntervalMomentum: true, + }); + } if (nativeEvent.oldState === State.BEGAN) { this.isDragWithHandle = true; // If we pull down the drawer with the handle, we set this value to compensate the amount of scroll on the FlatList @@ -294,6 +306,12 @@ export class ScrollBottomSheet extends Component> { this.dragY.setValue(0); this.lastSnap = destSnapPoint - (didScrollUpAndPullDown ? this.lastStartScrollYValue : 0); + if (Platform.OS === 'ios') { + // @ts-ignore + this.iOSMasterDrawer?.current?.setNativeProps({ + maxDeltaY: this.lastSnap - this.getNormalisedSnapPoints()[0], + }); + } }; onHandlerStateChange = ( @@ -340,7 +358,13 @@ export class ScrollBottomSheet extends Component> { }).start(() => { // @ts-ignore this.contentComponentRef.current?._component?.setNativeProps({ - decelerationRate: this.lastSnap === snapPoints[0] ? 0.985 : 0, + decelerationRate: + this.lastSnap === snapPoints[0] + ? Platform.OS === 'ios' + ? 0.998 + : 0.985 + : 0, + disableIntervalMomentum: false, }); if (this.didScrollUpAndPullDown) { // Compensate values between startScroll (set it to 0) and restore the final amount from translateYOffset; @@ -388,7 +412,12 @@ export class ScrollBottomSheet extends Component> { } = this.props; const AnimatedScrollableComponent = this.scrollComponent; - return ( + const drawerContentSimultaneousHandlers = + Platform.OS === 'ios' + ? [this.scrollComponentRef, this.iOSMasterDrawer] + : [this.scrollComponentRef]; + + const Content = ( extends Component> { @@ -407,7 +439,7 @@ export class ScrollBottomSheet extends Component> { extends Component> { extends Component> { // @ts-ignore ref={this.contentComponentRef} overScrollMode="never" - decelerationRate={initialSnapIndex === 0 ? 0.985 : 0} + decelerationRate={ + initialSnapIndex === 0 + ? Platform.OS === 'ios' + ? 0.998 + : 0.985 + : 0 + } onScrollBeginDrag={this.onScrollBeginDrag} onMomentumScrollEnd={this.handleMomentumScrollEnd} scrollEventThrottle={1} @@ -433,6 +472,22 @@ export class ScrollBottomSheet extends Component> { ); + + if (Platform.OS === 'android') { + return Content; + } + + return ( + + + {Content} + + + ); } }