I have an issue with scroll view inside Swipe model using react-native-modals. The problem is in Android the scrolling is smooth and working perfectly. However, with iOS scrolling is with short amount only it scrolls for tiny amount then it stops meaning i have to repeat scrolling for 10 times over the screen to view the bottom with small contents only. This is the code for the model.
<Modal
propagateSwipe={true}
visible={this.props.visible}
useNativeDriver={true}
modalAnimation={
new SlideAnimation({
initialValue: 0, // optional
slideFrom: 'bottom', // optional
useNativeDriver: false, // optional
})
}
style={stylesSwipeCard.modal}
rounded={true}
modalStyle={[
stylesSwipeCard.customModal,
this.props.customModalStyle,
{maxHeight: height * this.props.height},
]}
onTouchOutside={() => this.props.closeModal(false)}
swipeDirection={['down']} // can be string or an array
swipeThreshold={100} // default 100
onSwipeOut={(event) => {
this.props.closeModal(false);
}}
containerStyle={stylesSwipeCard.modalContainer}
footer={this.props.hasFooter && this.props.footerContent}>
<ModalContent style={stylesSwipeCard.modalContent}>
<View
style={[stylesSwipeCard.container, this.props.modalContainerStyle]}>
<Image source={line_swipe} style={{alignSelf: 'center'}} />
<ScrollView>
<TouchableHighlight>
<TouchableWithoutFeedback>
<View>{this.props.children}</View>
</TouchableWithoutFeedback>
</TouchableHighlight>
</ScrollView>
</View>
</ModalContent>
I would appreciate any help or suggestions π. Thanks
Related
In react native i'm using "react-native-dropdown-picker" library to make a dropdown, the problem is that when i open the picker it stays under the next view, so i decided to use zindex and i managed to place the picker on top of the next view, the problem is that i can't click on any of the options, when i click any of the dropdown's options, the touch is recognized on the view under the picker.
The following code is the code for the toolbar component where the dropdown is stored.
<View style={styles.toolbar}>
<View style={{flexDirection:'row',alignItems:'center',justifyContent:'space-between',width:'100%'}}>
<TouchableWithoutFeedback onPress={() => {props.toggleDrawer()}} >
<View style={styles.menu}>
<View style={styles.menuBar}/>
<View style={styles.menuBar}/>
<View style={styles.menuBar}/>
</View>
</TouchableWithoutFeedback>
{logo}
</View>
<DropDownPicker
items={condominiumsList}
defaultValue={condominium}
containerStyle={{height: 45}}
style={styles.formBoxes}
labelStyle={{fontFamily:'segoeui4',fontSize:14,flex:1}}
dropDownStyle={styles.formBoxes}
onChangeItem={item=>{condominiumInputHandler(item.value)}}
/>
</View>
And this code shows where the toolbar is used and the view thats under it:
<NavigationContainer>
<View style={{...styles.default,...styles.marginTopPhone}}>
<ToolbarLogged toggleDrawer={()=>{navigation.toggleDrawer()}}
idLang={(stringLang==strings_pt)?1:2} lang={stringLang}/>
<DrawerCustom.Navigator drawerContent={props => <DrawerContent langFile={stringLang} lang={(stringLang==strings_pt)? 1 : 0} {...{...props}}/>}>
<DrawerCustom.Screen name='Dashboard' component={makeLayout} initialParams={{ name: stringLang.dashboard}}/>
<DrawerCustom.Screen name='Condominium' component={makeLayout} initialParams={{ name: stringLang.condominium}}/>
<DrawerCustom.Screen name='Profile' component={makeLayout} initialParams={{ name: stringLang.profile}}/>
<DrawerCustom.Screen name='Signout' component={Signout} />
</DrawerCustom.Navigator>
</View>
</NavigationContainer>
The makeLayout function, makes the current layout depending on the name param thats given, and as u can see if i dont use zindex on the superior view of the toolbar, the dropdown gets loaded under the screen given by the makelayout function, and if i use zindex then i cant select any of the options on the dropdown.
I have a FlatList and I'm implementing a custom pull to refresh, and the idea is to scroll it to a negative offset to reveal the animation underneath it upon release. Here's the code for my FlatList.
const flatListRef = useRef(null);
const handleRelease = () => {
flatlistRef.current.scrollToOffset({ y: -100 });
setTimeout(() => {
flatlistRef.current.scrollToOffset({ y: 0 });
}, 1000)
}
return (
<FlatList
data={data}
renderItem={({ item }) => {
return (
<View style={styles.row}>
<Text style={styles.text}>{item}</Text>
</View>
)
}}
onScroll={onScroll}
scrollEventThrottle={16}
onResponderRelease={handleRelease}
ref={flatListRef}
/>
)
Upon releasing, the FlatList should scroll to offset -100 to reveal the animation underneath, and then scrolls back up after 1 second. But what's happening is that it is scrolling to offset 0 (I could tell because I tried scrolling down immediately upon releasing, it will immediately try to scroll back up).
Is it possible to programmatically scroll the FlatList to a negative offset?
It looks you need to set scrollToOverflowEnabled to true to apply this behavior.
ScrollView(Flatlist inherits ScrollView Props )
PS:
Here is a different idea.
Maybe you can add a fixed height View if you wanna go to -100. (looks same)
And after time set the view close. (back to origin position?)
(If it doesn't work....)
------------------edit-----
<FlatList
data={data}
renderItem={({ item }) => {
return (
<View style={styles.row}>
<Text style={styles.text}>{item}</Text>
</View>
)
}}
onScroll={onScroll}
scrollEventThrottle={16}
onResponderRelease={handleRelease}
ref={flatListRef}
scrollToOverflowEnabled={true} // Just put in here
/>
Use offset instead of y as the parameter key for scrollToOffset as stated in the docs:
flatlistRef.current.scrollToOffset({ offset: -100 });
Since I heard this from RN docs 'Never put a flat list inside scroll view wrapper'.
But I have one huge page to make and it requires a scroll itself, and there are children flat lists as well.
Of course, this causes a horrible scroll lag user experience, so there is anyone experienced the same kind of problem as me? What was a solution to this?
This is my snippet.
<View style={{ flex: 1 }}>
<ScrollView
ref={c => this.detailScrollView = c}
style={{ flex: 1, backgroundColor: "#f8faf9" }}
>
<FlatList1 goodsDetails />
<FlatList2 goodsPriceSelector />
<FlatList3 bestreviews />
<FlatList4 sellerGoods />
<FlatList5 sameCategoryGoods />
</ScrollView>
</View>
edit:
Today, thanks to #MaieonBrix I replaced my childeren flatlists to SectionLists, could feel a bit of improvement. In test android build it still janky, but I think I'm on the right track. I will keep this updated.
{descImgs && !!descImgs.length ?
<SectionList
sections={descImgs.slice(0,2)}
ref={c => this.goodsDesc = c}
style={{ marginTop: 22, marginBottom: 22 }}
keyExtractor={item => item}
renderItem={function ({ img }) {
return (
<View style={{ alignSelf: "center" }}>
{img.includes("https://") ? (
<FastImage
resizeMode={FastImage.resizeMode.contain}
style={{ height: width, width: width, }}
source={{ uri: img }}
/>
) : <TextNoScailing>μμΈμ΄λ―Έμ§κ° μμ΅λλ€.</TextNoScailing>}
</View>
);
}.bind(this)}
/>
Well thats true.Flatlist would not work fine under scrollview in android because both using same gestures in same direction.Possible solutions
1) You can define your custom gestures using pan responder library "which is a bit tough for a biggner"
2) Disable/Enable scroll using conditions.e-g: When you're touching a flatlist then disable scroll of scrollView Similarly when on scrollView then disable for Flatlist.
The above solution is for android only because for iOS it will work fine automatically.Similarly you've to provide horizontal margin for flatlist container .Becuse only then use can touch the scroll view container near the boundries.
Hope it clears
I have a very frustrating situation. Trying to get keyboard to disappear and detect onPress event handler in child row.
Here is what my code looks like:
_renderRow = (prediction) => {
return (
<TouchableOpacity onPress={() => {
Keyboard.dismiss();
this.setState({ location: prediction.description });
}}>
<View style={styles.listItemContainer}>
<Text>{prediction.description}</Text>
</View>
</TouchableOpacity>
)
}
render() {
return (
<View style={styles.wrapper}>
{/* style={[this.state.predictions.length > 0 ? styles.searchContainerSuggest : styles.searchContainer]} */}
<View style={styles.searchContainerSuggest}>
<View style={{paddingLeft: 10, height: 45, display: 'flex', justifyContent: 'center'}}>
<TextInput
placeholder="Enter location"
value={this.state.location}
onChangeText={location => this.onChangeLocation(location)}
style={styles.textInput}
/>
</View>
{this.state.predictions.length && this.state.location !== '' ?
<FlatList
keyboardShouldPersistTaps={'handled'}
refreshing={!this.state.loaded}
initialNumToRender={10}
enableEmptySections={true}
data={this.state.predictions}
keyExtractor={(_, index) => index.toString()}
renderItem={ ({item: prediction}) => this._renderRow(prediction) } />
: null}
</View>
</View>
);
}
I probably need a helping hand or two with regards to how to debug this issue.
Looked up several examples on how to deal with hiding the keyboard and allowing a particular selection to be pressed at the same time.
I thought that keyboardShouldPersistTaps would allow for the child selection to be selected. Upon selection, the onPress event handler will trigger and that will be where I call Keyboard.dismiss() to hide the keyboard. Does not seem to work.
In my case, besides adding keyboardShouldPersistTabs='handled' to the FlatList in question, it was also needed to add keyboardShouldPersistTabs='handled' and nestedScrollEnabled={true} to a parent ScrollView like 2 levels above, wrapping the FlatList I intended to get this behavior with. Check out this issue in react-native repo for more info.
For anyone who is running into the same problem as me. Check whether your FlatList or ScrollView is nested in another FlatList or ScrollView.
If yes, then add
keyboardShouldPersistTaps='handled'
to the element as a props as well.
add keyboardDismissMode="none" to FlatList
I'm trying to make my Modal slide up and bounce on button click, but it's not working when I wrap the Modal into an Animated.View component. It's only sliding up because of the animationType prop but afterwards nothing happens. Any ideas?
//in render() function
<Animated.View
style={{
flex: 1,
transform: [ // `transform` is an ordered array
{ scale: this.state.bounceValue }, // Map `bounceValue` to `scale`
],
}}
>
<Modal
animationType={"slide"}
transparent={true}
visible={this.state.modalVisible}
>
<View style={styles.modalContainer}>
<View style={styles.modalInnerContainer}>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
/>
</View>
</View>
</Modal>
</Animated.View>
// onPress function
_onSelectFilter(rowID) {
if (this.state.modalVisible) {
this.state.bounceValue.setValue(2);
Animated.spring(
this.state.bounceValue,
{
toValue: 0.8,
friction: 1,
}
).start();
}
}
It's not entirely clear in the docs, but <Modal/> in React Native is contained in a native-level view separate from your main React Native container. This means you don't have much control over it.
If you need additional control, you'll need to use a top-level view and not <Modal/>.
If your app is simple, you can simply add a view with absolute positioning at the root level.
// Modal content goes inside here
<View style={{position: 'absolute', top: 0, right: 0, bottom: 0, left: 0}}>
</View>
With more complex apps, you might want to integrate this into your Navigation strategy.