React Native - Stacking app header content - react-native

I'm trying to stack content in the Navigation top bar that is being set using the setOptions method. However, I can't seem to stack vertically two pieces of content. Instead, I can only show a single piece of content. Keep in mind this header bar has no true navigation linking and is purely a "title" bar with text and imagery. It is also within the same component I use to actually create my navigation with createBottomTabNavigator().
What I would like is, pseudo-visually:
<Text><Image><Text>
<Text>
Here is my code:
navigation.setOptions({
headerTitle: (
<Text
style={{
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap',
}}
>
<Text
style={{
fontSize: 16,
lineHeight: 16,
}}
>
Left Text{' '}
</Text>
<Image
source={require('../assets/images/icon-large.png')}
style={{ resizeMode: 'contain', width: 25, height: 25 }}
/>
<Text
style={{
fontSize: 16,
lineHeight: 16,
}}
>
{' '}
Right Text
</Text>
</Text>
),
});
which gives me, pseudo-visually:
<Text><Image><Text>
Now, i've tried various layout's of <View> and <Text> and just cant seem to get the stacking visual im looking for. I've tried wrapping it all with a <View> and then a last <Text> but I believe the headerTitle property needs a <Text> or type string assigned to it.
Any suggestions how I can get another <Text> underneath (and centered) what I have already?

With a combination of this and moving the navigation settings to the Stack.Screen I was able to get what I wanted. My problem seemed to be that I was trying to set the header options within BottomTabNavigator. Instead, if I passed in a custom "Header" component, it rendered the way I wanted it. Like so:
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Scroll Rack"
options={{ headerTitle: (props) => <Header /> }}
component={BottomTabNavigator}
/>
</Stack.Navigator>
</NavigationContainer>

You need to have a View which behaves as a row inside a View which behaves as a column. In the example below, the first View as flexDirection: 'column' as default.
<View style={{backgroundColor: "#ff0000"}}>
<View style={{flexDirection: 'row', justifyContent: "space-between", backgroundColor: "#00ff00"}}>
<Text>Left</Text>
<Image
source={{uri: "https://miro.medium.com/max/712/1*EnF9uIN_u2_X7ey24lB7Tg.png"}}
style={{ resizeMode: 'contain', width: 25, height: 25 }}
/>
<Text>Right</Text>
</View>
<Text style={{textAlign: "center"}}>Bottom</Text>
</View>
Here's a snack of it

Related

Can't align 2 views vertically and horizontally in React-Native

I have 2 Views One view on the left that have 2 items aligned next to each other, and the other is on the right like this, and on IOS it's worse
The problem as you can see here the name is not align to the arrow, I can't figure what the reason is. Here is my code:
<View style={styles.header}>
<View style={styles.leftHeader}>
<TouchableOpacity onPress={() => navigation.goBack()}>
<ArrowLeft />
</TouchableOpacity>
<View>
<Text style={styles.username}>{user && user.username}</Text>
</View>
<TouchableOpacity
onPress={() => setMoreModalVisible(true)}
style={styles.twoDots}>
<TwoDots />
</TouchableOpacity>
</View>
and here is the styling:
header: {
paddingHorizontal: wp(3),
flexDirection: 'row',
marginTop: hp(2.5),
marginBottom: hp(1),
justifyContent: 'space-between',
alignItems: 'center',
},
leftHeader: {
flexDirection: 'row',
justifyContent: 'flex-start',
textAlignVertical: 'center',
},
username: {
fontFamily: semiBoldFont,
fontSize: 15,
paddingLeft: wp(3),
},
Check the style of <ArrowLeft /> component. There might be some padding or margin applied there.
Or provide us with a snack for you code so we can be able to help you.
You can't change the height of the header because the headerStyle prop doesn't have a height prop.
You can follow the docs reference on this link:
https://reactnavigation.org/docs/headers#adjusting-header-styles
Another way to modify the header style you can set the headerShown prop to false and build your own header in the component where you can define the view height of your custom header, but be carefully because if you turn of the header in react-navigation then you have to use the safeareaview from react-native-safe-area-context because your screen will be slip up. On Android you don't take care about this.
A little code snipett for the example:
<Stack.Screen
name="example"
component={Component}
options={{headerShown: false}}
/>
function Component() {
const headerHeight = Platform.OS === 'ios' ? 44 : 20
return (
<SafeAreaView edges={["top"]}>
<View style={{height: headerHeight}}>
// your custom header content
</View>
</SafeAreaView>
)
}

Cant Use onPress() Events on Animated.View set to Position: Absolute - React Native

I made a scrollable header for an app I am building for a company. When I try to use a TouchableHighlight to trigger an onPress() event it does not register because the position key is set to 'absolute':
Ive tried the following after scouring the internet for hours:
-raising the zIndex/elevation
-making sure TouchableHighlight is imported from 'react-native'
-Animated library from 'react-native-reanimated'
When I comment out the position:absolute in the main header it works perfectly, but the header leaves a view behind it when it scrolls up that I cant lay a view on top of.
I'm running out of options here...any help would be GREATLY appreciated!
<Animated.View style={globalStyles.tabNavbar}>
<TouchableHighlight
style={{backgroundColor: 'white', height: 50, width: 100, zIndex: 99999, elevation: 99999}}
underlayColor="#eee"
onPress={() => {
console.log('PLZ WORK');
this.updateTabs('projectsTab');
}} >
<Animated.View style={{ alignItems: 'center'}}>
<Text onPress={() => { this.updateTabs('projectsTab');}} style={{fontWeight: 'bold'}}>Close</Text>
</Animated.View>
</TouchableHighlight>
<TouchableHighlight
style={{color: 'white'}}
underlayColor="#eee"
onPress={() => {
console.log('PLZ WORK');
this.updateTabs('notificationTab');
}} >
<View style={{alignItems: 'center'}}>
<Text style={{fontWeight: 'bold'}}>Close</Text>
</View>
</TouchableHighlight>
</Animated.View>
For those wondering, If you alter the View order of the Components to where the component with position: absolute is last, the buttons will work. In this situation I had to put my header last in the order even though it appears at the top of my screen.

How can a nested ScrollView expand to 100% its height in React Native?

I have a main ScrollView for a user profile, and then within that ScrolllView I call a component that is also a ScrollView with the same vertical orientation.
I'm looking to expand the nested component so its height is 100% of the content within it. Currently, the height appears to be around the height of the screen, while the content within it appears to be much longer.
The code I currently have looks like this:
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ marginTop: HEADER_MAX_HEIGHT, paddingBottom: HEADER_MAX_HEIGHT * 1.5 }}>
...irrelevant code here
{showSub && <Sub uid={uid} /> }
</ScrollView>
Where Sub is broadly defined as this, I've removed some unnecessary code from this example:
<ScrollView style={{ flex: 1 }}
contentContainerStyle={{ marginTop: 0, paddingBottom: 0 }}
scrollEventThrottle={2}
onScroll={this.onScroll}
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={this.onRefresh} />}
>
...irrelevant code here
<View>
{categories && Object.keys(categories).map((category, catIndex) => {
let currentCategory = categories[category]
let collections = currentCategory['data']
let categoryName = currentCategory['categoryName']
return (
<View key={category}>
<TouchableOpacity style={{ flex: 1 }} onPress={() => this.props.navigation.navigate('Category', { category })}>
<Text style={{ flex: 1, fontSize: 28, fontWeight: 'bold', marginTop: 15, marginLeft: generalPadding }}>
{categoryName}
</Text>
</TouchableOpacity>
</View>)}
</View>
</ScrollView>
I've tried height: "100%" for the ScrollView, but that didn't achieve the desired height.
Welp, I was able to solve this by wrapping the content in a View with height of 100%.

Align text and image on the same line React Native

I'm trying to align a text and an image that are wrapped in a text element in React Native.
This is what it currently looks like:
I'd like to have it aligned so it's even across.
This is the code I currently have:
<Text>
<Text
key={i}
onPress={() => this.updateCurrentFilter(i)}
style={{
paddingLeft: 10,
fontFamily: "Montserrat-Regular",
fontSize: 12,
}}
>{v.filter_name}</Text>
<Image
source={require('../assets/outline_toggle_off_black_18dp.png')}
style={{
width: 25,
height: 25,
color: 'black',
resizeMode: 'contain',
}}
/>
</Text>
Something like this should work. It's not clear why you're wrapping the outer level in a Text field instead of a View
<Text>
<View style={{flexDirection:'row', alignItems:'center'}}>
<Text style={{....}}}>foo</Text>
<Image ... />
</View>
</Text>

React Native Absolute Positioned Component elements onPress events not working

I created a custom dropdown component which has a transparent Scrollview with ToucableOpacity elements. However the onPress on them are not working, even though, zIndex is making them appear on top of everything else.
In the main screen, I created two elements, 1 header containing the Dropdown and 2nd one is the body which contains the rest. Its code is given below:
<View style={styles.body, {zIndex:0}}>
<View style={[styles.header,{zIndex:1}]}>
<Text style={styles.header_text}>Search In </Text>
<Dropdown items={CATEGORIES}/>
</View>
<View style={[styles.main,{zIndex:-1}]}>
<Text style={{backgroundColor:'blue'}}>I am the body</Text>
</View>
<View>
I have included the render event markup of the Dropdown element. Its code is given below:
<View style={styles.container}>
<TouchableOpacity style={styles.main_container} onPress={this.animate}>
<Text style={styles.text}>{this.state.selectedCategoryText}</Text>
<Text>-V-</Text>
</TouchableOpacity>
<View style={{zIndex:3}}>
<Animated.View style={[styles.animated_container,{opacity: this.opacity, zIndex:4}]}>
<ScrollView style={{height:60,zIndex:4}}>
{ this.data.map( (item, i)=>
<TouchableOpacity
style={{zIndex:5}}
disabled={this.state.disabled}
key={i}
onPress={()=>this.selectItem(i)}>
<Text >{item} {i}</Text>
</TouchableOpacity>
)}
</ScrollView>
</Animated.View>
</View>
</View>
Styles for Dropdown are:
container:{
zIndex:2
},
main_container:{
flexDirection: 'row',zIndex:2
},
text:{
fontFamily: fontStyles.PoppinsRegular,
fontSize: moderateScale(14)
},
animated_container:{
backgroundColor: colors.secondaryWhiteColor,
position: 'absolute',
top: '100%',
width: '100%',
zIndex:3
}
Screenshot is given as. zIndex makes the elements appear on top but i cannot trigger onPress on Toucable opacities.