how to use TapGestureHandler on Class Components - react-native

I'm trying to add a tap gesture to the render card of react-native-deck-swiper using the TapGestureHanlder from react-native-reanimated.
Currently, it works when tapping the red zone outside the swiper, but I want to tap the picture and get the x position where I tapped.
This is the code of the red zone, there I'm calling a class component in which I'm using the deck-swiper with some extra functions.
const onSingleTapEvent = (event) => {
if (event.nativeEvent.state === State.ACTIVE) {
alert('Hey single tap!');
}
};
return (
<GestureHandlerRootView style={{ zIndex: 10 }}>
<TapGestureHandler onHandlerStateChange={onSingleTapEvent}>
<AnimatedView style={styles.container}>
<ImageSwiperDeck
index={index}
listOfAssetsWithinTheAlbum={listOfAssetsWithinTheAlbum}
moveImageToTrashBin={moveImageToTrashBin}
keepImageInAlbum={keepImageInAlbum}
/>
</AnimatedView>
</TapGestureHandler>
</GestureHandlerRootView>
);
};
const styles = StyleSheet.create({
container: {
height: 560,
width: 500,
zIndex: 10,
backgroundColor: 'red',
},
});
export default ImageSwiper;
This is the deck-swiper code which works fine.
return (
<Swiper
ref={(swiper) => {
this.swiper = swiper;
}}
cards={this.props.listOfAssetsWithinTheAlbum}
cardIndex={this.props.index}
renderCard={this.Card}
backgroundColor={'transparent'}
onSwipedLeft={this.deleteImage}
onSwipedRight={this.keepImage}
cardVerticalMargin={10}
stackSize={5}
stackScale={20}
stackSeparation={5}
animateOverlayLabelsOpacity
animateCardOpacity
disableTopSwipe
disableBottomSwipe
overlayLabels={{
left: {
title: 'DELETE',
style: {
label: {
backgroundColor: colors.red,
borderColor: colors.red,
color: colors.white,
borderWidth: 1,
fontSize: 24,
},
wrapper: {
flexDirection: 'column',
alignItems: 'flex-end',
justifyContent: 'flex-start',
marginTop: 20,
marginLeft: -20,
},
},
},
right: {
title: 'KEEP',
style: {
label: {
backgroundColor: colors.blue,
borderColor: colors.blue,
color: colors.white,
borderWidth: 1,
fontSize: 24,
},
wrapper: {
flexDirection: 'column',
alignItems: 'flex-start',
justifyContent: 'flex-start',
marginTop: 20,
marginLeft: 20,
},
},
},
}}
/>
);

Related

My React native button text is not appearing in iOS but in android it works fine

Problem:
In my react native application I have used tochableOpacity for my buttons. I have created a custom button component and Have reused it through out the Application. My Custom button component is look like this.
const SubmitButton = (props) => {
const { onpress, btext, loadding, disabled, scrollView } = props;
const isLargeScreen = useIsLargeDevice();
return (
<TouchableOpacity
style={scrollView ? styles.sendButtonScrollView : styles.sendButton}
onPress={onpress}
disabled={disabled}>
{loadding ? (
<Image
source={spinner}
style={scrollView ? styles.bimageScrollview : styles.bimage}
/>
) : (
<Text
style={[
styles.sendButtonText,
isLargeScreen ? styles.largeText : styles.text,
]}>
{btext}
</Text>
)}
</TouchableOpacity>
);
};
export default SubmitButton;
const styles = StyleSheet.create({
sendButton: {
flex: 1,
backgroundColor: '#3e92ff',
paddingTop: '6%',
paddingBottom: '6%',
alignItems: 'center',
borderRadius: 50,
marginTop: 25,
justifyContent: 'center',
// flexWrap: 'wrap'
},
sendButtonScrollView: {
flex: 1,
backgroundColor: '#3e92ff',
paddingTop: '3%',
paddingBottom: '3%',
alignItems: 'center',
borderRadius: 50,
marginTop: 25,
justifyContent: 'center',
},
sendButtonText: {
fontFamily: 'Montserrat-Medium',
color: '#ffffff',
fontWeight: '300',
textAlign: 'center',
letterSpacing: 2,
},
text: {
fontSize: normalize(14),
},
largeText: {
fontSize: normalize(13),
},
bimage: {
width: 48,
height: 48,
},
bimageScrollview: {
width: 25,
height: 25,
},
});
And I have used it in another component like this.
Platform.OS === 'ios' ? Icon.loadFont() : null;
const handleBackButton = () => {
return true;
};
const _navigateToLogin = (navigation) => {
navigation.navigate('Login');
};
const _onPress = (values, validateToken) => {
validateToken(values.token);
};
const Tocken = (props) => {
useEffect(() => {
BackHandler.addEventListener('hardwareBackPress', handleBackButton);
}, [props.navigation]);
useEffect(() => {
if (props.validtoken === true) {
_navigateToLogin(props.navigation);
props.cleardata();
}
}, [props]);
return (
<KeyboardAvoidingView style={styles.container} enabled behavior={Platform.OS === 'ios' ? 'height' : null}>
<View style={styles.colmty} />
<View style={styles.formContainer}>
<AppText styles={styles.loginFormTitle}>
{strings('token.title')}
</AppText>
<Formik
initialValues={{
token: '',
}}
validationSchema={Yup.object({
token: Yup.string().required(strings('token.token-validation')),
})}
onSubmit={(values, formikActions) => {
_onPress(values, props.validatetoken);
setTimeout(() => {
formikActions.setSubmitting(false);
}, 500);
}}>
{(formprops) => (
<View>
<View
style={
!formprops.values.token &&
!formprops.errors.token &&
!props.hasError
? styles.inputView
: formprops.values.token &&
!formprops.errors.token &&
!props.hasError
? styles.validInputView
: styles.inputViewError
}>
<TextInput
style={styles.textField}
placeholder={strings('token.token_place_holder')}
placeholderTextColor="#bbbbbb"
value={formprops.values.token}
onChangeText={formprops.handleChange('token')}
onBlur={formprops.handleBlur('token')}
keyboardType="default"
/>
{formprops.errors.token || props.hasError ? (
<Icon
name="times"
size={normalize(15)}
style={styles.errorIcon}
/>
) : null}
{formprops.values.token &&
!formprops.errors.token &&
!props.hasError ? (
<Icon
name="check"
size={normalize(15)}
style={styles.validIcon}
/>
) : null}
</View>
{formprops.touched.token &&
formprops.errors.token &&
!props.hasError ? (
<View style={styles.errorMessage}>
<AppText styles={styles.errorMessageText}>
{formprops.errors.token}
</AppText>
</View>
) : null}
{props.hasError ? (
<View style={styles.errorMessage}>
<AppText styles={styles.errorMessageText}>
{props.error}
</AppText>
</View>
) : null}
<View style={styles.submitButtonView}>
<SubmitButton
btext={strings('token.submit')}
onpress={formprops.handleSubmit}
loadding={props.loadding}
disabled={props.loadding}
/>
</View>
</View>
)}
</Formik>
</View>
<View style={styles.colmty2} />
<View style={styles.hr} />
<View style={styles.versionContainer}>
<AppText styles={styles.version}>version: {version}</AppText>
</View>
</KeyboardAvoidingView>
);
};
const mapStateToProps = (state) => {
return {
loadding: state.signin.loadding,
validtoken: state.signin.validtoken,
hasError: state.signin.tokenEr,
error: state.signin.error,
};
};
const mapDispatchToProps = (dispatch) => {
return {
validatetoken: (value) => dispatch(signinActions.validatetoken(value)),
cleardata: () => dispatch(signinActions.cleardata()),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Tocken);
styles that I have used in the Token component is looks like this.
import {StyleSheet} from 'react-native';
import normalize from '_utils/fontsize';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ffffff',
},
colmty: {
height: '20%',
},
formContainer: {
height: '55%',
// backgroundColor: '#f2f2f2',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
// elevation: 5,
padding: '10%',
justifyContent: 'center',
paddingBottom: '5%',
},
colmty2: {
height: '10%',
},
bottom: {
height: '15%',
justifyContent: 'center',
alignItems: 'center',
},
hr: {
borderBottomColor: '#c3c3c3',
borderBottomWidth: 2.0,
marginRight: '10%',
marginLeft: '10%',
},
validIcon: {
marginTop: 15,
color: '#3e92ff',
},
errorIcon: {
marginTop: 15,
color: '#ff3d3d',
},
textField: {
flex: 1,
fontFamily: 'Montserrat-Medium',
fontSize: normalize(15),
fontWeight: '500',
paddingLeft: 0,
},
inputView: {
marginTop: '5%',
flexDirection: 'row',
borderBottomColor: '#cccccc',
borderBottomWidth: 2,
},
validInputView: {
marginTop: '5%',
flexDirection: 'row',
borderBottomColor: '#3e92ff',
borderBottomWidth: 2,
},
inputViewError: {
marginTop: '5%',
flexDirection: 'row',
borderBottomColor: '#ff3d3d',
borderBottomWidth: 2,
},
patientFormTitle: {
fontSize: 30,
fontWeight: '200',
fontStyle: 'normal',
textAlign: 'center',
color: '#444444',
alignItems: 'center',
},
bottomLinkText: {
fontSize: 13,
color: '#484848',
borderBottomWidth: 2,
borderBottomColor: '#c3c3c3',
},
loginFormTitle: {
fontSize: normalize(16),
fontWeight: '200',
fontStyle: 'normal',
textAlign: 'center',
color: '#444444',
alignItems: 'center',
marginTop: '-10%',
},
errorMessageText: {
color: '#ff3d3d',
fontSize: normalize(13),
marginTop: 10,
},
spinnerContainer: {
marginTop: '50%',
alignItems: 'center',
},
versionContainer: {
marginRight: '10%',
marginLeft: '10%',
marginTop: '10%',
},
version: {
textAlign: 'center',
fontSize: normalize(12),
},
});
export default styles;
But button is not showing the text it looks like this.
I tried lot to find out where I have done wrong but I was unable to do so. Can someone help me to solve this issue.Thank you

React Native view being pushed up and height changes dynamically when keypad pops out

I am designing an app in React Native and the problem I am facing right now is when I try to type in the TextBox, the keypad comes up and it pushes up or out the view changing height dynamically of other views too. Please check the Before and After image below:
The Code:
import React, { Component } from 'react';
import t from 'tcomb-form-native'; // 0.6.9
const Form = t.form.Form;
import {
StyleSheet,
View,
KeyboardAvoidingView,
TouchableOpacity,
ToastAndroid
} from 'react-native';
import { RFPercentage, RFValue } from "react-native-responsive-fontsize";
const styles = StyleSheet.create({
parentSectionContainer: {
flex: 1,
justifyContent: 'space-evenly',
backgroundColor: '#F1F0F2'
},
SignupFormParent: {
marginTop: 100,
alignSelf: 'center',
backgroundColor: '#FFFFFF',
height: '45%',
width: '85%',
borderRadius: 100,
shadowColor: '#2AC062',
shadowOpacity: 0.4,
shadowOffset: { height: 10, width: 0 },
shadowRadius: 20,
},
textMelow: {
width: RFPercentage(10),
fontSize: RFPercentage(2),
fontWeight: "normal",
color: '#FFFFFF',
textTransform: 'uppercase',
fontStyle: 'normal'
},
textBold: {
width: RFPercentage(10),
fontSize: RFPercentage(2),
fontWeight: "bold",
color: '#FFFFFF',
textTransform: 'uppercase',
fontStyle: 'normal'
},
btnContainer: {
paddingTop: 8,
width: '100%',
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
alignContent: 'center'
},
signupBodyStyle: {
position: "absolute",
bottom: 0,
width: '90%',
marginBottom: 20,
},
signinSignupButtonsBtnsContainer: {
flex: 1,
flexDirection: 'column',
justifyContent: 'flex-end',
alignItems: 'center',
width: '100%'
},
signupButtonBodyStyle: {
flex: 1,
backgroundColor: '#8A56AC',
borderRadius: 100,
alignItems: 'center',
padding: 25
},
signinSignupTextStyle: {
color: '#FFFFFF',
fontSize: 18,
}
});
const User = t.struct({
name: t.String,
email: t.String,
password: t.String,
"Confirm Password": t.String,
location: t.String
});
const SignupForm = (props) => {
const options = {
auto: 'placeholders',
};
return (
<View style={styles.SignupFormParent}>
<View style={{ paddingLeft: 20, paddingRight: 20, marginTop: 80 }}>
{/* <Text style={styles.text}>FORM</Text> */}
<Form type={User} options={options}/>
</View>
</View>
);
};
const ContinueButton = (props) => {
const { onPress, style } = props;
return (
<TouchableOpacity onPress={onPress} style={style.bodyStyle}>
<View
style={style.buttonStyle}>
<Text style={style.textStyle}>{props.title}</Text>
</View>
</TouchableOpacity>
);
}
export default class SignUpView extends Component {
// constructor(props) {
// }
fetch('${Config.IP}:${Config.PORT}/login', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'jayndoe#foobar.com',
password: "jynd1234",
}),
})
.then(response => response.json())
.then(responseJson => {
ToastAndroid.showWithGravity(
JSON.stringify(responseJson),
ToastAndroid.SHORT,
ToastAndroid.CENTER,
);
})
.catch(error => {
ToastAndroid.showWithGravity(
JSON.stringify(error),
ToastAndroid.SHORT,
ToastAndroid.CENTER,
);
})
}
render() {
return(
<View style={styles.parentSectionContainer}>
<KeyboardAvoidingView style={{ position: 'absolute', top: 0, width: '100%', backgroundColor: '#8A56AC', height: '30%', borderBottomLeftRadius: 120 }}/>
<View style={{ position: 'absolute', top: 50, width: '100%', flexDirection: 'row', justifyContent: 'space-evenly', margin: 'auto' }}>
<Text style={styles.textBold}>LOG IN</Text>
<Text style={styles.textMelow}>SIGN UP</Text>
</View>
<SignupForm
title="SIGN UP USING INSTAGRAM"
onPress={() => {this.instagramSSO()}}
style={{formStyles: styles.formStyles}}
/>
<View style={{ flex: 1, flexDirection: 'column', alignItems: 'center' }}>
<ContinueButton
title="CONTINUE"
style={{ bodyStyle: styles.signinBodyStyle, buttonStyle: styles.signinButtonBodyStyle, textStyle: styles.signinSignupTextStyle }}
onPress={() => Alert.alert('Please sign-in!!')}
/>
</View>
</View>
);
}
}
Appreciate any help in resolving this issue :)
This is because of the absolute positionning of your views,
I think you used it because you needed to put the white input wrapper on top of the purple one view. Maybe you could remove the absolute positionning and use negative paddingTop on the white wrapper instead ? I am not sure how to achieve this using good practices, but that could prevent the keyboardavoidingview to push your other components.

React Native: How to set <TextInput> and <Image> at center together

I want the text and image to be on one line and centered.
How can I center it?
I updated my code with another require
SearchBox will center when start, and then click to start type, it will be margin left (sorry guys, my english so bad).
constructor(props: any) {
super(props);
this.state = {
onEdit: false,
}
this.onBlur = this.onBlur.bind(this);
this.onEndEditing = this.onEndEditing.bind(this);
}
private onBlur() {
this.setState({
onEdit: true
});
}
private onEndEditing() {
this.setState({
onEdit: !this.state.onEdit
});
}
private get searchView() {
const { onEdit } = this.state;
return (
<View style={styles.searchContainer}>
<View style= {[styles.search, onEdit === true || this.props.keyword.length !== 0 ? undefined : { justifyContent: 'center' }]}>
<Image source={searchIcon} style={[styles.image, { marginLeft: onEdit === true || this.props.keyword.length !== 0 ? 10 : 0 }]} />
<TextInput
style={styles.searchInput}
placeholder={'search'}
onEndEditing={this.onEndEditing}
onFocus={this.onBlur}
defaultValue={this.props.keyword}
clearButtonMode="while-editing"
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
searchContainer: {
height: 72,
padding: 16,
},
search: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
height: 40,
},
image: {
marginRight: 10,
alignSelf: 'center'
},
searchInput: {
paddingRight: 10,
fontSize: 14,
},
})
Update: I got a new error when I type text in search box. It was hidden for the first few characters.
You need to use flex instead of flexBox.
Here you go:
render() {
return (
<View style={styles.container}>
<View style={styles.searchContainer}>
<Image source={IC_PRIVATE_CLUB_NORMAL} style={styles.image} />
<TextInput
style={styles.searchInput}
placeholder={'search'}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
searchContainer: {
height: 72,
width: '90%',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'pink',
flexDirection: 'row'
// padding: 16,
// paddingLeft: 10,
// paddingRight: 10,
// flex: 1,
},
search: {
// width: '80%',
flexDirection: 'row',
alignItems: 'center',
height: 60,
backgroundColor: 'gray'
},
image: {
marginRight: 10,
alignSelf: 'center'
},
searchInput: {
height: 40,
width: '80%',
fontSize: 14,
textAlign: 'center',
backgroundColor: 'red'
},
})

react-native headerTitleStyle

I am using the StackNavigator and was trying to align the word 'topic' to center vertically. However, adjusting padding and margin does not seem to help. I believe the space above the word is to cater to the status bar. Is there a way around this? The StackNavigator code is below.
See image
export const MyAppStack = StackNavigator({
Topic: {
screen: TopicScreen,
navigationOptions: {
title: 'Topic',
headerStyle: {
backgroundColor: 'grey',
elevation: null,
paddingTop: 0,
height: 10,
marginTop: 0 },
headerTitleStyle: {
paddingTop: 0,
alignSelf: 'center',
justifyContent: 'center'
}
},
},
FlashCard: {
screen: FlashCardScreen,
navigationOptions: {
title: 'Flashcards',
headerBackTitleStyle: {
fontSize: 100,
alignSelf: 'center'
}
},
},
});
I am also attaching the header style (the top portion) for reference but I don't think the problems lies with it. Thanks in advance!
const Header = (props) => {
const { textStyle, viewStyle } = styles;
return (
<View style={viewStyle}>
<Text style={textStyle}>{props.headerText}</Text>
</View>
);
};
const styles = {
viewStyle: {
backgroundColor: '#ff8a00',
justifyContent: 'center',
alignItems: 'center',
height: 60,
paddingTop: 15,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.2,
elevation: 2,
position: 'relative'
},
textStyle: {
fontSize: 20
}
};
Remove alignSelf: 'center' from ...
headerTitleStyle: {
paddingTop: 0,
alignSelf: 'center',
justifyContent: 'center'
}

React-Native - Can't find variable: title

New React-Native installation. I am trying to set it up. In index.ios.js, I have:
class thingy extends Component {
render() {
return (
<NavigatorIOS
style={styles.container}
initialRoute={(
title: 'Thingy',
component: Main
)} />
);
}
}
When I run this, the app gives me the error:
Can't find variable: title
I'm not sure why it's giving me this error. Any ideas?
Main Component:
var React = require('react-native');
var {
View,
Text,
StyleSheet
} = React;
var styles = StyleSheet.create({
mainContainer: {
flex: 1,
padding: 30,
marginTop: 65,
flexDirection: 'column',
justifyContent: 'center',
backgroundColor: '#48BBEC'
},
title: {
marginBottom: 20,
fontSize: 25,
textAlign: 'center',
color: '#fff'
},
searchInput: {
height: 50,
padding: 4,
marginRight: 5,
fontSize: 23,
bordderWidth: 1,
borderColor: 'white',
borderRadius: 8,
color: 'white'
},
buttonText: {
fontSize: 18,
color: '#111',
alignSelf: 'center'
},
button: {
height: 45,
flexDirection: 'row',
backgroundColor: 'white',
borderColor: 'white',
borderWidth: 1,
bordeRadius: 8,
marginBottom: 10,
marginTop: 10,
alignSelf: 'stretch',
justifyContent: 'center'
},
});
class Main extends React.Component{
render(){
return (
<View style={styles.mainContainer}>
<Text> Testing the Router </Text>
</View>
)
}
};
module.exports = Main;
Ah, it looks like initialRoute should be an object, but you have it wrapped in parenthesis:
How it is now:
initialRoute={(
title: 'Thingy',
component: Main
)}
Should actually be:
initialRoute={{
title: 'Thingy',
component: Main
}}