По расспрашивал все чаты. Решение не нашел.
Сейчас чтобы скрол контента на экране включился, я довожу родителя до самого верха и нужно поднять палец, тогда скрол контента включиться.
Нужно чтобы не поднимая пальца скрол включился при достижении верхней грницы экрана родителем при свайпе.
То есть я поднимаю родителя свайпом вверх, и если продолжаю свайпить вверх то нужно чтобы переключился свайп на скрол контента не поднимая пальцы.
Сейчас палец нужно поднять.
И при закрытии также нужно поднять палец чтобы скрол отключился когда тяну вниз.
Помогите пожалуйста.
import React, { useEffect, useRef, useState } from 'react';
import {
Modal,
View,
Text,
StyleSheet,
TouchableOpacity,
Animated,
Dimensions,
Image,
PanResponder,
Alert,
ScrollView,
} from 'react-native';
const screenWidth = Dimensions.get('window').width;
const screenHeight = Dimensions.get('window').height;
const INITIAL_POSITION = screenHeight * 0.4;
const Screen1 = ({ navigation }) => {
const [isScrollEnabled, setScrollEnabled] = useState(false);
const [isOverlayVisible, setOverlayVisible] = useState(true);
const slideAnim = useRef(new Animated.Value(INITIAL_POSITION)).current;
const currentPosition = useRef(INITIAL_POSITION);
const scrollViewRef = useRef(null); // Реф для ScrollView
useEffect(() => {
slideAnim.setValue(screenHeight);
Animated.timing(slideAnim, {
toValue: INITIAL_POSITION,
duration: 400,
useNativeDriver: true,
}).start();
}, []);
const panResponder = useRef(
PanResponder.create({
onMoveShouldSetPanResponder: (_, gestureState) => {
// Разрешаем родителю захватывать свайп, если ScrollView неактивен или вверху
return Math.abs(gestureState.dy) > 10 && (!isScrollEnabled || gestureState.dy > 0);
},
onPanResponderMove: (_, gestureState) => {
const newPosition = Math.max(0, currentPosition.current + gestureState.dy);
slideAnim.setValue(newPosition);
setOverlayVisible(newPosition < screenHeight * 0.7);
// Включаем ScrollView только если модалка в самом верху
setScrollEnabled(newPosition <= 0);
},
onPanResponderRelease: (_, gestureState) => {
currentPosition.current = slideAnim._value;
if (currentPosition.current > screenHeight * 0.7) {
Animated.timing(slideAnim, {
toValue: screenHeight,
duration: 300,
useNativeDriver: true,
}).start(() => {
navigation.goBack();
});
} else {
Animated.spring(slideAnim, {
toValue: currentPosition.current,
useNativeDriver: true,
}).start();
}
},
})
).current;
// Обработчик прокрутки ScrollView
const handleScroll = (event) => {
const scrollY = event.nativeEvent.contentOffset.y;
// Если ScrollView в самом верху, отключаем его, чтобы передать свайп родителю
if (scrollY <= 0) {
setScrollEnabled(false);
}
};
return (
<View style={styles.fullScreen}>
{isOverlayVisible && <View style={styles.backgroundOverlay} />}
<Animated.View
style={[styles.overlay, { transform: [{ translateY: slideAnim }] }]}
{...panResponder.panHandlers}
>
<View style={[styles.container, { backgroundColor: '#eee', flex: 1 }]}>
<View style={[styles.section, { backgroundColor: '#eee',height:200 }]}>
<Text style={[styles.sectionT, { fontSize: 19 }]}>
БЛОК ПОД КОТОРЫМ СКОЛЛ
</Text>
</View>
<ScrollView
ref={scrollViewRef}
scrollEnabled={isScrollEnabled}
onScroll={handleScroll}
scrollEventThrottle={16}
>
<View style={{marginRight:20}}>
<View style={{ position: 'relative' }}>
<View style={{height:200,margin:30,padding:20,backgroundColor:'#000'}}><Text>qwe</Text></View>
<View style={{height:200,margin:30,padding:20,backgroundColor:'#000'}}><Text>qwe</Text></View>
<View style={{height:200,margin:30,padding:20,backgroundColor:'#000'}}><Text>qwe</Text></View>
<View style={{height:200,margin:30,padding:20,backgroundColor:'#000'}}><Text>qwe</Text></View>
<View style={{height:200,margin:30,padding:20,backgroundColor:'#000'}}><Text>qwe</Text></View>
<View style={{height:200,margin:30,padding:20,backgroundColor:'#000'}}><Text>qwe</Text></View>
<View style={{height:200,margin:30,padding:20,backgroundColor:'#000'}}><Text>qwe</Text></View>
<View style={{height:200,margin:30,padding:20,backgroundColor:'#000'}}><Text>qwe</Text></View>
</View>
</View>
</ScrollView>
</View>
</Animated.View>
</View>
);
};
const styles = StyleSheet.create({
fullScreen: {
flex: 1,
position: 'absolute',
top: 0,
left: 0,
width: screenWidth,
height: screenHeight,
},
backgroundOverlay: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
overlay: {
position: 'absolute',
top: 0,
left: 0,
width: screenWidth,
height: '100%',
zIndex: 1000,
},
modalOverlay: {
flex: 1,
backgroundColor: '#00000088',
justifyContent: 'center',
alignItems: 'center',
},
});
export default Screen1;