I have a login form with two text inputs stacked vertically and a container view with two buttons below the inputs:
I want the two buttons to stretch to fill the width of the button container (red), so each button would take half its size. However I can't get it to work. I've tried various combinations of flex* properties with no luck.
In native iOS I would use a UIStackView for this with orientation = horizontal. React Native documentation says that pretty much any layout can be achieved with flexbox.
This is what my component looks like right now:
import React, {Component} from 'react';
import {KeyboardAvoidingView, TextInput, View, StyleSheet} from 'react-native';
import Button from 'react-native-button';
export default class Login extends Component {
render() {
return (
<KeyboardAvoidingView style={styles.container}>
<TextInput
placeholder="LOGIN"
placeholderTextColor="#505050"
style={styles.input}/>
<TextInput
placeholder="PASSWORD"
placeholderTextColor="#505050"
style={styles.input}/>
<View style={styles.buttonContainer}>
<Button
onPress={() => this.logIn()}
style={[styles.button, styles.loginButton]}>
Log in
</Button>
<Button
onPress={() => this.register()}
style={[styles.button, styles.registerButton]}>
Register
</Button>
</View>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingHorizontal: 16,
backgroundColor: 'lightgray'
},
input: {
height: 40,
marginBottom: 12,
paddingHorizontal: 8,
backgroundColor: 'white'
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red'
},
button: {
padding: 8,
color: 'white',
backgroundColor: 'steelblue'
},
loginButton: {
marginRight: 8
}
});
If I add flex: 1 to the button style they become:
What am I doing wrong?
Yes. Its because of the react-native-button component. You have to use the containerStyle property of the Button component to style the container.
import React, {Component} from 'react';
import {KeyboardAvoidingView, TextInput, View, StyleSheet} from 'react-native';
import Button from 'react-native-button';
export default class Login extends Component {
render() {
return (
<KeyboardAvoidingView style={styles.container}>
<TextInput
placeholder="LOGIN"
placeholderTextColor="#505050"
style={styles.input}/>
<TextInput
placeholder="PASSWORD"
placeholderTextColor="#505050"
style={styles.input}/>
<View style={styles.buttonContainer}>
<Button
onPress={() => this.logIn()}
style={styles.buttonText}
containerStyle={styles.button}
>
Log in
</Button>
<Button
onPress={() => this.register()}
style={styles.buttonText}
containerStyle={styles.button}
>
Register
</Button>
</View>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingHorizontal: 16,
backgroundColor: 'lightgray'
},
input: {
height: 40,
marginBottom: 12,
paddingHorizontal: 8,
backgroundColor: 'white'
},
buttonContainer: {
height: 60,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red'
},
button: {
flex: 2,
padding: 8,
backgroundColor: 'steelblue',
alignSelf: 'stretch',
justifyContent: 'center',
},
buttonText: {
color: 'white',
}
});
Related
React Native alert defaults to showing up at the center of the screen. I've been trying to style it so that it shows up at the bottom of the screen - with no success. Does anyone know how I would go about this? I tried position: absolute and bottom: 0 but it still shows up in the center.
I have tried this out let me know if it helps also have designed according to the image.
Copy Paste the code and try.
import React, { useState } from 'react';
import {
StyleSheet,
View,
Text,
TextInput,
Pressable,
Modal,
Dimensions,
Button,
} from 'react-native';
const App = () => {
const [showWarning, SetshowWarning] = useState(false);
const onPressHandler = () => {
SetshowWarning(true);
}
return (
<View style={styles.body}>
<Modal
visible={showWarning}
transparent
onRequestClose={() =>
SetshowWarning(false)
}
animationType='slide'
hardwareAccelerated
>
<View style={styles.centered_view}>
<View style={styles.warning_modal}>
<View style={styles.warning_title}>
<Text style={{
color: '#000000',
fontSize: 25,
fontWeight:'700',
textAlign: 'center',
}}>Unsaved Changes</Text>
<Text style={styles.text}>Are you sure you want to continue?</Text>
</View>
<Pressable
onPress={() => SetshowWarning(false)}
style={styles.warning_button1}
android_ripple={{ color: '#fff' }}
>
<Text style={styles.textKE}>Keep Editing</Text>
</Pressable>
<Pressable
onPress={() => SetshowWarning(false)}
style={styles.warning_button}
android_ripple={{ color: '#fff' }}
>
<Text style={styles.textDC}>Discard Changes</Text>
</Pressable>
</View>
</View>
</Modal>
<Button onPress={() =>onPressHandler()} title="Text This"></Button>
{/* Add Here full code */}
</View >
);
};
const styles = StyleSheet.create({
body: {
flex: 1,
backgroundColor: '#ffffff',
alignItems: 'center',
},
centered_view: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#00000099',
},
warning_modal: {
width: Dimensions.get('window').width,
height: 200,
backgroundColor: '#eeff0f0',
borderRadius: 20,
top:"31%"
},
warning_title: {
height: 100,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#eff0f0',
borderTopRightRadius: 20,
borderTopLeftRadius: 20,
borderBottomWidth:1,
borderColor:'grey'
},
warning_body: {
height: 100,
justifyContent: 'center',
alignItems: 'center',
},
textKE: {
marginTop:20,
color: '#1485fe',
fontSize: 20,
margin: 5,
textAlign: 'center',
},
textDC: {
marginTop:20,
color: 'red',
fontSize: 20,
margin: 5,
textAlign: 'center',
},
warning_button1: {
height:70,
backgroundColor: '#efeff0',
borderBottomWidth:1,
borderColor:'grey'
},
warning_button: {
height:70,
backgroundColor: '#efeff0',
borderBottomLeftRadius: 20,
borderBottomRightRadius: 20,
}
});
export default App;
I'm new to coding and react native, so sorry if this is a stupid question.
I'm having issues rendering a hamburger icon from the following code. It works as expected on Android but not iOS.
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Image } from 'react-native';
import { totalPoints, totalBucks } from '../datasets/UserData.js';
export class Navbar extends React.Component {
constructor(props){
super(props);
}
burgerPress = value => {
this.props.onPress();
}
render(){
var points = totalPoints;
var bucks = totalBucks;
return(
<View style={styles.row}>
<Text style={styles.column} />
<Text style={styles.column}>
<Image source={require('../../assets/coins.png')} style={{ width: 30, height: 30, resizeMode: 'contain'}}/>
{" "}{ points }
</Text>
<Text style={styles.column}>
<Image source={require('../../assets/bills.png')} style={{ width: 40, height: 40, resizeMode: 'contain'}}/>
{" "}{ bucks }
</Text>
<View style={styles.column}>
<TouchableOpacity onPress={() => this.burgerPress()} style={{width: 40, height: 40, justifyContent: 'center', alignItems: 'center'}}>
<Image source={require('../../assets/hamburger.png')} resizeMode={'contain'} style={{ width: 40, height: 40, backgroundColor: 'lightblue', tintColor: '#ffffff', justifyContent: 'center', alignItems: 'center'}}/>
</TouchableOpacity>
</View>
</View>
);
};
};
const styles={
row: {
flex: 1,
alignItems: 'flex-end',
flexDirection: 'row',
borderBottomWidth: 1,
borderColor: "#000000",
padding: 5,
justifyContent: 'center'
},
column: {
flex: 1,
alignItems: 'center',
flexDirection: 'column',
justifyContent: 'center'
}
}
The coins and bills icons load properly on both platforms. The hamburger loads on android, but on iOS, all I get is the background color. If I delete the backgroundColor and tintColor, it renders nothing, so I think the issue is that it is not importing the image at all but only on iOS. Is there any way to get this to work?
iOS display(unexpected)
Android display(expected)
I don't see what your styles.column are specified as but as a test I would give your TouchableOpacity a width and height as well. Then try to set justifyContent: center and alignItems: center to make sure the image is not being hidden for some reason.
You might also need to specify the resizeMode={'contain'} prop in Image rather than just declaring it in your image style.
I'm looking to dismiss the keyboard when the user clicks on anywhere outside the keyboard or the input, but the keyboard is not being dismissed when I click elsewhere:
<TouchableWithoutFeedback style={styles.container} onPress={Keyboard.dismiss}>
<View style={styles.inputContainer}>
<TextInput
placeholder="Search Term"
style={styles.input}
onChangeText={setSearch}
value={search}
returnKeyType="search"
onSubmitEditing={handleSubmit}
/>
</View>
</ TouchableWithoutFeedback>
The styling is pretty standard:
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
inputContainer: {
position: 'absolute',
top: stackHeaderHeight + 10,
height: height * .1,
width: '100%',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
You need to change your onPress code of TouchableWithoutFeedback
<TouchableWithoutFeedback style={styles.container} onPress={()=> Keyboard.dismiss()}>
</ TouchableWithoutFeedback>
Sample working code.
render() {
return (
<TouchableWithoutFeedback onPress={()=>Keyboard.dismiss()} >
<View style={{ flex: 1 }}>
<TextInput returnKeyType="search" style={{borderWidth:1,borderColor:'grey',marginTop:100,height:50,marginHorizontal:50}}/>
</View>
</TouchableWithoutFeedback>
);
}
I think you have a problem with your style properties. Please check on your container and inputcontainer style properties. If you have any ScrollView in your render method add following
<ScrollView keyboardShouldPersistTaps='always'>
Very strange behavior, I am using a FlatList, and on top of it there are 2 floating buttons (TouchableOpacity) (absolute position) and when they are pressed, their background color turns black.
This happens only on IOS.
Code:
Render
let content = (
<CollapsableNavList
onListScroll={this.showOrHideFilterButtons}
showFilterButtonsOnScroll={this.showOrHideFilterButtons}
style={styles.list}
isHorizontal={false}
dataModel={this.props.isFetching ? this.props.whileFetchingDisplayedResults : this.props.dataModel}
isFetching={false}
onRowSelect={this._onRowSelect}
didScrollWithOffset={this.didScrollWithOffset}
renderRowContent={this.renderRowContent}
keyExtractor={(item) => {
if (this.props.isFetching) {
return item
}
const property = item
return property.propertyId
}}
>
{header}
</CollapsableNavList>
)
return (
<View style={[styles.container, styles.relative]}>
<View style={styles.filterBtnBlock}>
<AdditionalSearchParamsButton
title='Map'
iconName='map'
onPress={this.onMapPress}
/>
</View>
{content}
</View>
)
export default class AdditionalSearchParamsButton extends Component {
// Prop type warnings
static propTypes = {
iconName: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
onPress: PropTypes.func.isRequired
}
render () {
const { iconName, title, onPress } = this.props
return (
<View>
<TouchableHighlight onPress={onPress} underlayColor={Colors.clear}>
<View style={styles.innerContainer}>
<McIcon
name={iconName}
style={styles.additionalPropsIcon}
/>
<Text style={styles.additionalPropsText}>{title}</Text>
</View>
</TouchableHighlight>
</View>
)
}
}
export default StyleSheet.create({
container: {
height: 50,
width: 150,
alignItems: 'center',
justifyContent: 'center'
},
innerContainer: {
height: 36,
width: 126,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: Colors.snow,
borderRadius: 18,
elevation: 2,
shadowOffset: {width: 0, height: 2},
shadowColor: 'black',
shadowOpacity: 0.3,
marginBottom: 5,
},
additionalPropsBtn: {
height: 36,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: Colors.snow
},
additionalPropsText: {
...Fonts.style.bigTitle,
color: Colors.blue,
paddingLeft: 10
},
additionalPropsIcon: {
fontSize: 22,
color: Colors.blue
}
})
What I've tried:
-Setting underlays color to clear, with no success.
-Adding different layers under, no success.
-This only happens when displayed on a list, happens with ListView too.
Please use TouchableOpacity instead of TouchableHighlight
TouchableHighlight Highlight the background when you click
Try add this <TouchableHighlight underlayColor='none' />
try this in your TouchableOpacity props
underlayColor="#ffffff00"
I have solved it using activeOpacity with background color
<TouchableOpacity activeOpacity={1} backgroundColor="#FFF"></TouchableOpacity>
You can use own backgroundColor
Wrap View with <TouchableHighlight underlayColor="#fff">
I'm using react-native latest release 0.4.4 and installed react-native-side-menu and react-native-carousel components.
For some reason when I run the app, it's not showing anything.
The code instantiate a view with sidemenu and contentview inside.
contentview is for displaying the main page which contains three buttons and when someone clicks on explore it takes them to search page using navigatorios component.
Is there is some problem with StyleSheet ?
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
Component,
NavigatorIOS,
View,
TouchableHighlight,
TextInput,
} = React;
var SideMenu = require('react-native-side-menu');
var Menu = React.createClass({
about: function() {
this.props.menuActions.close();
},
render: function() {
return (
<View>
<Text>Menu</Text>
<Text onPress={this.about}>About</Text>
</View>
);
}
});
var styles = StyleSheet.create({
searchView: {
flexDirection: 'row',
padding: 25,
marginTop: 100,
},
text: {
color: 'black',
backgroundColor: 'white',
fontSize: 30,
margin: 80
},
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#F5FCFF',
},
flowRight: {
flexDirection: 'column',
padding: 25,
alignItems: 'center',
alignSelf: 'stretch',
marginTop: 100,
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
button: {
height: 36,
flex: 1,
flexDirection: 'row',
backgroundColor: '#009D6E',
borderColor: '#008C5D',
borderWidth: 1,
borderRadius: 8,
marginBottom: 10,
alignSelf: 'stretch',
justifyContent: 'center'
},
buttonText: {
fontSize: 18,
color: 'white',
alignSelf: 'center'
},
});
class Search extends Component {
render() {
return (
<View style={styles.searchView}>
<TextInput
style={{ flex: 2, height: 40, borderColor: 'gray', borderWidth: 1, padding: 5, borderRadius: 5}}
onChangeText={(text) => this.setState({input: text})}
placeholder="Search Appointment" />
<TextInput
style={{ flex: 1, height: 40, borderColor: 'gray', borderWidth: 1, padding: 5, borderRadius: 5}}
onChangeText={(text) => this.setState({input: text})}
placeholder="Location" />
</View>
);
}
}
class Welcome extends React.Component {
onExplorePressed() {
this.props.navigator.push({
title: 'Explore',
component: Search,
});
}
render() {
return (
<View style={styles.flowRight}>
<Text style={styles.welcome}>
Welcome to Docit!
</Text>
<TouchableHighlight style={styles.button} underlayColor='#009D3E'>
<Text style={styles.buttonText}>Sign In with Facebook</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.button} underlayColor='#009D3E'>
<Text style={styles.buttonText}>Sign In with Email</Text>
</TouchableHighlight>
<Text style={styles.welcome}>OR</Text>
<TouchableHighlight
onPress={this.onExplorePressed.bind(this)}
style={styles.button}
underlayColor='#009D3E'>
<Text style={styles.buttonText}>Explore Something</Text>
</TouchableHighlight>
</View>
);
}
}
class ContentView extends Component {
render() {
return (
<NavigatorIOS
style={styles.container}
initialRoute={{
component: Welcome,
title: 'Welcome',
}}/>
)
}
}
var Docit = React.createClass({
render: function() {
var menu = <Menu navigator={navigator}/>;
return (
<SideMenu menu={menu}>
<ContentView/>
</SideMenu>
);
}
});
AppRegistry.registerComponent('Something', () => Something);
Am I doing something wrong here ??
I figured out that react-native-carousel component was conflicting with sidebar menu component and showing a blank screen. I posted the issue on their repository.
The simple solution is remove react-native-carousel component from everywhere, even from node_modules/, the folder inside.
Your react versions could be out of sync. I've had this happen to me when the react version bundled with the iOS app is different than the version that the packager is running.
If you're using cocoapods, make sure that the react version in your podfile is the same as your package.json.