Weird padding on React Native with SafeAreaView on iOS when scrolling - react-native

I am having an issue with React Native, #react-navigation/stack and headerMode='screen'. I have a screen with the header hidden. On iOS, in that specific view, when I perform some scrolling or even do the "pull gesture" from top to bottom, an extra margin / padding appears on top of the view.
This is how I define my screen in the navigation:
<Stack.Screen
name="AddressInput"
component={AddressInput}
options={{
headerShown: false,
}}
/>
My AddressInput component is like:
<SafeAreaView sx={{ flexDirection: 'column', flex: 1 }}>
<KeyboardAwareScrollView
contentContainerStyle={{
padding: theme.space[3],
flexGrow: 1,
}}
ref={scrollRef}
keyboardShouldPersistTaps="handled"
>
<Form
validationSchema={validationSchema}
initialValues={initialValues}
fields={fields}
>
<AddressFormFields/>
</Form>
</KeyboardAwareScrollView>
</SafeAreaView>
This works perfectly fine on Android. The header is hidden and the UI works as expected. But on iOS, when I perform scrolling on the view (or even pull down once from the top), an extra padding appears on top of the view and I have no idea why! I am not expecting this to happen.
I've tried dozens of various tricks and measures to find out the cause, but no success. Also referred to the official docs for hours. Any hints?
Attached images. On the second one you can see the text field has some padding compared to the other pic, but that only comes present after performing some scrolling.
(OK) after navigating to screen, but before scrolling
(NOT OK) after scrolling, some extra padding appears on top

Related

Change the drag of ListItem.Swipeable from React Native Elements

I've been using the Swipeable component from react-native-gesture-handler to handle my swipeable list items, but Swipeable is causing lag on the JS thread during the initial render, according to my profilers. So I've decided to switch to ListItem.Swipeable from React Native Elements. The initial render lag is gone, which is great, but it requires too much drag to swipe from left to right and vice versa. I've looked through the documentation of Listem.Swipeable, but I don't see any way to manipulate the drag.
Is there a way to change the drag value?
Relevant ListItemSwipeable component:
<ListItem.Swipeable
rightWidth={ScreenWidth / 2}
rightContent={() => <Buttons />}
>
<KeyboardAvoidingView style={{ flex: 1 }}>
<AccordionListItem item={item} />
</KeyboardAvoidingView>
</ListItem.Swipeable>

React Native missing pixels, when we put some separator or border in Flatlist separator or in map method for executing mutiple JSX items

In my React Native Project, I am trying to make some kind of lists using Flatlist or sometimes using map method, for executing JSX Element. I am getting the result correctly, But there is a bit of a problem in separate.
Let's take chatting app example, When we open WhatsApp there are a lot of people showing up, but there is also a tiny separator after each item, That looks great, Now exactly when I try to put that separator in my React Native application using ItemSeparatorComponent attribute in Flatlist, It's working but still in some places, meaning in some items that separator not showing up, its looks missing, it feels that there is no border/separator. And actually what's going on is that, the below item from that separator which is hidden or which height looks smaller than others, that below View go a little bit towards the upside, so the separator gets to hide, That's the main problem, Why is that happening, I tried everything but still, I am getting that UI problem.
Here is code example:
<FlatList
data={actionSheet._data}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
keyExtractor={(_, index) => index}
renderItem={({item, index}) => <ActionSheetClickableItem data={item} index={index}/> }
ItemSeparatorComponent={() => (
<View
style={{
height: 1,
width: '100%',
backgroundColor: 'red'
}}
/>
)}
/>
OR
<ScrollView>
{
actionSheet._data.map((item, index) => (
<>
<ActionSheetClickableItem data={item} index={index} key={index}/>
<View
style={{
height: 1,
width: '100%',
backgroundColor: 'red'
}}
/>
</>
))
}
</ScrollView>
So according to the above code, I know for sure, that everything is correct, But why is that separator get hidden, If we look at this picture in the area of the green rectangles, there is no border showing up, Why... I want to show it here, I tried to put zIndex property, that trick working correctly but that isn't the solution, It have to correct view as we expecting, why its behave like this, any solution??????
I was facing the same issue.
That might be with Emulator or Your screen.
You can use also increase the height of itemSeparater or make the background color more darker.
If you check it in real device then it displays all the separaters.

React Native Expo How to Hide Status and bar make component take that place

I am not able to fill the status bar area with component. I tried to do it by hiding the status bar using <StatusBar hidden />. But this one leaves a white space there. For example I want to fill the green image the status bar.
TLDR: working project link
On the gist link (you've provided on the comment), I can see that you are using the following structure
<SafeAreaView>
<StatusBar ... />
<ImageBackground ...></ImageBackground>
</SafeAreaView>
If you want to hide the status bar and cover the whole screen with the image you need to change SafeAreaView to just View and also remove StatusBar component.
<View>
<ImageBackground ...></ImageBackground>
</View>
Cause SafeAreaView will dynamically put some padding at the top. So although you've put style={{ height: '100%', width: '100%' }} it will respect the padding of SafeAreaView cause it is the parent component here.
Also at this point, you do not need StatusBar, cause the StatusBas already has an image as background.

Make draggable item above all others with React Native Animated.View and PanResponder

I have a render method with these components:
<View style={styles.root}>
{p.parts.map((part, index) =>
<Animated.View
key={`part${index}`}
style={[
this.draggables[index].pan.getLayout()
]}
{...this.draggables[index].panResponder.panHandlers}
>
<SphereView part={part} />
</Animated.View>
)}
</View>
And this style:
const styles = StyleSheet.create({
root: {
flexDirection: 'row'
}
});
Drag and drop is working, but the problem is that when I drag the second element, it is shown above only the first and below all others. I want the component being dragged to be above all others.
I've tried various combinations with zIndex and none worked.
How to do it?
Edit: I've now just achieved with with the "elevation" style in Android. Is it the correct approach (even for iOS)?
It's a shame that most of the PanResponder questions on SO (or at least the ones Ive seen) have no answer. You can use zIndex. Just set the zIndex to 999 or something during the drag, and then on release, set it to the original zIndex+1, so that it STAYS above the other images. If you kept all of the dragged elements at 999, they would no longer overlap after one drag.
Elevation only works on android, but zIndex works on both, and will not create a shadow/3D effect

Add content in bounce margin of ScrollView in React Native?

In my app I'm using <ScrollView /> to view pages of a book scrolling horizontally. When a user gets to the end of the <ScrollView /> there is a bounce that shows a white area to the right that is only visible if the user drags the last page to the left. I want to add some text there that says "The End" vertically. How can I add content to the right of the <ScrollView /> in the bounce area?
I ALMOST figured it out. This is close but shows up in the right side of the last page but not off the page on the right in the bounce area. I want it to show up "to the right of the page" not "on the right side of the page." Any other ideas?
Create a <View style={styles.end} /> with this style:
theEnd: {
position: 'absolute',
top: 0,
right: 0,
width: 100,
height: 768, // Device height
alignItems: 'center',
}
Place it right before the <ScrollView /> and put whatever you want to show inside of the View component with the "theEnd" style.
This probably doesn't apply to your content, but I had the same situation except with a large image for the ScrollView content. I wanted both horizontal and vertical scrolling, where the edge of the image would show up only in the bounce margin. I figured out that the scale transformation works great for this:
<ScrollView horizontal={true}>
<Image
source={require('./img/map.jpg')}
style={{transform: [{scale: 1.1}]}}
/>
</ScrollView>
So the image takes up 110% of the height and width of its box (which is then inside a yet smaller ScrollView).
EDIT: FYI, after testing, discovered this only works on iOS, not Android. (Android won't allow vertical scrolling if you set horizontal to true, and also I think it didn't render the parts outside of the normal viewing area, so the bounce margin was empty.)
there is a prop for this called contentContainerStyle
<ScrollView
horizontal={true}
contentContainerStyle={{
paddingLeft: 25,
paddingRight: 25,
}}>
*** CONTENT ***
</ScrollView>