How add tabs in react-native IOS using rn-viewpager - ios

I am using rn-viewpager for tabs in react-native. But I am having issues in opening new page on each tab selected.
I am using following link: react-native-viewpager
export default class ViewPagerPage extends Component {
render() {
return (
<View style={{flex:1}}>
<IndicatorViewPager
indicatorPosition="top"
style={{flex:1, paddingTop:20, backgroundColor:'white'}}
indicator={this._renderTitleIndicator()}
>
<View style={{backgroundColor:'cadetblue'}}>
<Text>page one</Text>
</View>
<View style={{backgroundColor:'cornflowerblue'}}>
<Text>page two</Text>
</View>
<View style={{backgroundColor:'#1AA094'}}>
<Text>page three</Text>
</View>
</IndicatorViewPager>
</View>
);
}
_renderTitleIndicator() {
return <PagerTitleIndicator titles={['Page1', 'Page2', 'Page3']} />;
}
return (
<PagerTabIndicator
tabs={tabs}
textStyle={{color:'#999'}}
selectedTextStyle={{color:'#111'}}
iconStyle={{width:25, height:25, tintColor:'#999'}}
selectedIconStyle={{width:25, height:25, tintColor:'#111'}}
/>
);
}
}
I want to open page.js file on click of every tab.

Related

React Native - IOS - Text strings must be rendered within a <Text> component

Looking at my code for few hours, I was not able to understand the root cause for this exception
Error: Text strings must be rendered within a <Text> component.
This error is located at:
in RCTView (created by View)
in View (created by Card)
in Card (created by StartGameScreen
Can anyone give me a hint? Where do I have to check analyzing? I have a Card component indeed. Is this the first place to check according to the error message?
Card
import {View, StyleSheet} from 'react-native'
import Colors from '../../constants/colors'
function Card({children}) {
return (
<View style = {styles.card}> {children} </View>
)
}
export default Card;
StartGameScreen
function StartGameScreen({onPickNumber}) {
const [enteredNumber, setEnteredNumber] = useState('')
function numberInputHandler(enteredText) {
setEnteredNumber(enteredText)
}
function resetInputHandler() {
setEnteredNumber('')
}
function confirmInputHandler() {
const choseNumber = parseInt(enteredNumber)
if (isNaN(choseNumber) || choseNumber <= 0 || choseNumber > 99) {
Alert.alert('Invalid number', 'Number has to be a number between 1 and 99', [{text:'Okay', style:'destructive', onPress:resetInputHandler}]);
return;
}
onPickNumber(choseNumber);
}
return (
<View style={styles.rootContainer}>
<Title>Guess my number</Title>
<Card>
<InstructionText>dsd</InstructionText>
<View style={styles.textInputContainer}>
<TextInput style={styles.numberInput} maxLength={2} keyboardType="number-pad" autoCapitalize='none' onChangeText={numberInputHandler} value={enteredNumber}/>
</View>
<View style = {styles.buttonsContainer}>
<View style={styles.buttonContainer}>
<PrimaryButton onPress={resetInputHandler}>Reset</PrimaryButton>
</View>
<View style={styles.buttonContainer}>
<PrimaryButton onPress={confirmInputHandler}>Confirm</PrimaryButton>
</View>
</View>
</Card>
</View>
)
}
InstructionText
function InstructionText({children}) {
return (
<Text style={styles.instructionText}>{children}</Text>
)
}
const InstructionText = ({children}) => {
return (
<Text style={styles.instructionText}>{children}</Text>
)
}
This should work !!
if you have spaces in your return statement, you have to wrapping it in parenthesis () and using one line per each tag.

How to make the React Native app to ask if I want to save username and password? (iOS 11+)

Based on this excellent question and answer, I tried to implement autofill function in my app. While the username and password sections can be auto-filled (i.e, Above the keyboard, there is a password button, and once I press the button, Face ID is activated, and I can select an option), but it does not ask when I typed a username and password and pressed the sign in button.
Any suggestion is very appreciated!
import { useForm } from 'react-hook-form';
// Just in case
// "#react-navigation/bottom-tabs": "^5.4.2",
// "#react-navigation/native": "^5.2.6",
// "#react-navigation/stack": "^5.3.1",
...
export default function screen({navigation, route}) {
useEffect(()=> {
register("email");
register("password")
return () => {
console.log("Unmounted");
}
}, [register]);
...
return (
...
<View
style={[
styles.container,
styles.emailSection,
styles.paddingHorizontal,
]}>
<View style={styles.textInputContainer}>
<TextInput
onChangeText={text => {
setValue('email', text);
}}
placeholder={'Email'}
placeholderTextColor="grey"
keyboardType="email-address"
autoCapitalize={'none'}
autoCorrect={false}
textContentType={'username'}
style={styles.textInputFont}
/>
</View>
<View style={styles.textInputContainer}>
<TextInput
onChangeText={text => {
setValue('password', text);
}}
placeholder={'Password'}
placeholderTextColor="grey"
keyboardType="default"
autoCapitalize={'none'}
autoCorrect={false}
secureTextEntry={true}
textContentType={'password'}
style={styles.textInputFont}
/>
</View>
<View>
<TouchableOpacity
onPress={
isEmailLoading ? null : handleSubmit(_onPressEmailSignIn)
}>
<View style={[styles.wideButtonContainer]}>
<Text style={styles.secondaryFont}>Sign In</Text>
</View>
</TouchableOpacity>
</View>
<View style={styles.textContainer}>
<TouchableOpacity
onPress={() => navigation.navigate('ForgotPassword')}>
<View>
<Text style={styles.secondaryFont}>Forgot Password</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
onPress={() => navigation.navigate('EmailSignUp')}>
<View>
<Text style={styles.secondaryFont}>Sign Up</Text>
</View>
</TouchableOpacity>
</View>
</View>
...
)
- Tried on simulator (iPhone Xs (12.0) and my device (iPhone Xr (13.0))

How did I use the push() function in NavigatorIOS?

I want to Push to a new Component by the function push() in NavigatorIOS. It's like following:
renderRow(rowData, sectionID, rowID) {
var imgSource = IMAGE_URLS[rowID];
return (
<TouchableHighlight onPress = {() => {
this.props.navigator.push({
title: 'test',
component: example,
});
}}>
<View>
<View style={styles.row}>
<Image
source={imgSource}
style={styles.thum}
/>
<Text style={styles.text}>
{rowData}
</Text>
</View>
</View>
</TouchableHighlight>
);
}
But it will get a error when I click the TouchableHighlight.
I refered these two questions(1 and 2) before this. And the complete code is in this link
this is not binded to the class inside of renderRow().
You have to bind this either in the constructor:
this.renderRow = this.renderRow.bind(this);
or inside the render method:
render() {
var navStatusBarConfig = {
style: 'light-content',
}
return (
<View style={{ flex: 1, backgroundColor: '#F5FCFF'}}>
<View styles={styles.nav}></View>
<ListView
automaticallyAdjustContentInsets={false}
contentContainerStyle={styles.list}
dataSource={this.state.dataSource}
pageSize={4}
renderRow={this.renderRow.bind(this)}
/>
</View>
);
}
}
As to why, here is the reason :
https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding
And a more complete blog about how to bind this [there are many, blogs and ways to bind this]) :
http://blog.andrewray.me/react-es6-autobinding-and-createclass/

TouchableHighlight one click not work two works

I am having a strange problem. I wrote up a simple player app with react native and everything is fine in simulator. But when it comes to real device, its play button does not work properly. I tried the app on iPhone 6s and iPhone 5. The problem is that the play button works at second tap. The first tap does nothing.
Here is my whole render code:
render() {
let playIcon = this.state.isPlaying ? 'pause' : 'play';
let titleA = 'Set A: ' + (this.state.isASet ? this._toTime(this.state.pointA) : '-');
let titleB = 'Set B: ' + (this.state.isBSet ? this._toTime(this.state.pointB) : '-');
let time = this._toTime(this.state.time);
let remaining = this._toTime(this.state.duration - this.state.time);
return (
<View style={styles.container}>
<View style={styles.info}>
<Text>Name: {this.props.song.name}</Text>
<Text>Artist: {this.props.song.artist.name}</Text>
<Text># of channels: {this.props.song.tracks.length}</Text>
</View>
<View style={styles.channels}>
{
this.props.song.tracks.map((track, index) => {
return (
<VolumeSlider
key={index}
title={track.name}
volume={this.state.channelVolumes[index]}
onVolumeChange={this._handleChannelVolumeChange.bind(this, index)}
onMutePress={this._handleChannelMutePress.bind(this, index)}
onSoloPress={this._handleChannelSoloPress.bind(this, index)}
isPlayingSolo={this.state.channelSolos[index]}
/>
);
})
}
<VolumeSlider
title='Main'
volume={this.state.mainVolume}
onVolumeChange={this._handleMainVolumeChange.bind(this)}
onMutePress={this._handleMainMutePress.bind(this)}
hideSolo={true}
/>
</View>
<View style={{flexDirection: 'row', justifyContent: 'center'}}>
<TouchableHighlight style={styles.button} onPress={this._handleAPress.bind(this)}>
<Text numberOfLines={1}>{titleA}</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.button} onPress={this._handleBPress.bind(this)}>
<Text numberOfLines={1}>{titleB}</Text>
</TouchableHighlight>
<TouchableHighlight
style={styles.button}
onPress={this._handleClearLoopPress.bind(this)}
>
<Text numberOfLines={1}>Clear</Text>
</TouchableHighlight>
</View>
<View style={styles.player}>
<TouchableHighlight onPress={this._handlePlayPress.bind(this)}>
<Icon
name={playIcon}
style={styles.playButton}
/>
</TouchableHighlight>
<View style={styles.center}>
<Text style={styles.timelineText}>{time}</Text>
</View>
<View style={styles.sliderContainer}>
<Slider
style={[styles.slider, styles.timelineSlider]}
onSlidingComplete={this._handleTimelineChange.bind(this)}
maximumValue={this.state.duration}
value={this.state.time}
step={0.01}
/>
</View>
<View style={styles.center}>
<Text style={styles.timelineText}>-{remaining}</Text>
</View>
</View>
</View>
);
}
And this is how it looks like on simulator:
I tried changing the location of the play button (I mean I placed it at the top of the app) and it worked. But I don't understand why it does not work when it is at bottom-left corner?
Thank you for your answers.
I found the problem. The problem is NavigatorIOS which is parent of the PlayerScreen of which render function is given belove. The navigator has swipe back gesture and it blocks the first tap on the play button. When I disabled the swipe back gesture of the navigator by falsing its interactivePopGestureEnabled pro, the play button properly worked.

React-native: Why rendering an empty view component creates an error while a text component runs?

I am trying to create an array of View components in react-native that are passed to a parent component. The code below does not work, however if i use Text instead of View it works. I want use view to show empty or filled circles. I couldn't find the reason for it and i assume it should be possible to use an empty view. What am i doing wrong?
class card extends React.Component {
renderScore(balance, fulfill, markImage){
var scores = [];
for (i = 1; i <= fulfill; i++) {
if(i<=balance){
if (markImage) {
scores.push(<View style={styles.emptyCircle} key={i}> </View>);
//scores.push(<View style={styles.emptyCircle} key={i}> <Image source={{uri: markImage}} style={styles.markImage}/> </View>);
}
else{
scores.push(<View style={styles.emptyCircle} key={i}> <View style={styles.punchCircle}></View> </View>);
}
}
else
{
scores.push(<View style={styles.emptyCircle} key={i}> </View>);
}
}
return(scores);
}
}
This will give 'RawText " " must be wrapped in an explicit component.'
However if use
scores.push(<Text style={styles.emptyCircle} key={i}> </Text>);
it works.
It is called from a ListView as
_renderCard(item){
var cardBottom = new cardRenderer();
var childView = cardBottom.renderScore(item.balance, item.fulfill, item.markImage);
console.log(childView);
return(
<View style={styles.mainConatiner}>
<View style={styles.leftConatiner}>
<Image
source={{uri: item.avatarLeft}}
style={styles.thumbnail}
/>
</View>
<View style={styles.rightConatiner}>
<View style={styles.rightUpConatiner}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.title}>{item.subTitle}</Text>
<Text style={styles.title}>{item.expires}</Text>
</View>
<View style={styles.rightDownConatiner}>{childView}</View>
</View>
</View>
);
}
Use below for empty view
return(<></>)
try this
return(<View>{scores}</View>);

Resources