React native modal does not behave as expected - react-native

I am new to React native. I am using one package called #react-native-community/datetimepicker. I have one button and inside the button I have create one Modal. when user will click the button it will open the modal. My logic works fine but the problem is my modal behave weird. when I open and close the modal one big black-screen pop up all the time. I really don't know how to fix. I followed this Youtube-tutorial for the modal. I share my code in expo-snacks.
This is my all code
import React, { useState } from 'react';
import { Modal, Platform, StyleSheet, Text, TouchableHighlight, View } from 'react-native';
import dayjs from 'dayjs';
import DateTimePicker from "#react-native-community/datetimepicker";
export default function App() {
const [date, setDate] = useState(new Date());
const [show, setshow] = useState(false);
const onChange = (event, selectedDate) => {
const currentDate = selectedDate || date;
setshow(Platform.OS === `ios`);
setDate(currentDate);
};
const onCancelPress = () => {
};
const onDonePress = () => {
};
return (
<View style={{marginTop: 20}}>
<TouchableHighlight
activeOpacity={3}
onPress={() => setshow(true)}
>
<View style= {{
"flex": 1,
"marginBottom": 40
}}>
<View>
<Text style={{
"paddingleft": 15,
"paddingTop": 8,
"paddingBottom": 35,
"borderColor": `gray`,
"borderWidth": 1,
"borderRadius": 10,
"fontSize": 20 }}> {dayjs(date).format(`DD/MM/YYYY`)} </Text>
</View>
<Modal
transparent= {true}
animationType="slide"
visible={show}
supportedOrientations={[`portrait`]}
onRequestClose={() => setshow(false)} >
<View style={{ "flex": 1 }}>
<TouchableHighlight
style={{
"flex": 1,
"alignItems": `flex-end`,
"flexDirection": `row`
}}
activeOpacity={1}
visible={show}
onPress={() => setshow(false)}
>
<TouchableHighlight
underlayColor={`#FFFFFF`}
style={{
"flex": 1,
"borderTopColor": `#E9E9E9`,
"borderTopWidth": 1
}}
onPress={() => console.log(`datepicker picked`)}
>
<View
style={{
"backgroundColor": `#FFFFFF`,
"height": 256,
"overflow": `hidden`
}}
>
<View style={{ "marginTop": 20 }}>
<DateTimePicker
value={date}
mode="date"
is24Hour={true}
display="default"
onChange={onChange}
/>
</View>
</View>
</TouchableHighlight>
</TouchableHighlight>
</View>
</Modal>
</View>
</TouchableHighlight>
</View>
);
}

Use TouchableOpacity instead of TouchableHighlight to get rid of that flashing black box.
Working app: Expo Snack
import React, { useState } from 'react';
import {
Modal,
Platform,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import dayjs from 'dayjs';
import DateTimePicker from '#react-native-community/datetimepicker';
export default function App() {
const [date, setDate] = useState(new Date());
const [show, setshow] = useState(false);
const onChange = (event, selectedDate) => {
const currentDate = selectedDate || date;
setshow(Platform.OS === `ios`);
setDate(currentDate);
};
const onCancelPress = () => {};
const onDonePress = () => {};
return (
<View style={{ marginTop: 30 }}>
<TouchableOpacity activeOpacity={3} onPress={() => setshow(true)}>
<View>
<View>
<Text
style={{
paddingleft: 15,
paddingTop: 8,
paddingBottom: 35,
borderColor: `gray`,
borderWidth: 1,
borderRadius: 10,
fontSize: 20,
}}>
{dayjs(date).format(`DD/MM/YYYY`)}{' '}
</Text>
</View>
<Modal
transparent={false}
animationType="slide"
visible={false}
onRequestClose={() => setshow(false)}>
<View
style={{
flex: 1,
}}>
<TouchableOpacity
style={{
flex: 1,
alignItems: `flex-end`,
flexDirection: `row`,
}}
activeOpacity={0.5}
onPress={() => setshow(false)}>
<TouchableOpacity
style={{
flex: 1,
borderTopColor: `#E9E9E9`,
borderTopWidth: 1,
}}
onPress={() => console.log(`datepicker picked`)}>
<View
style={{
backgroundColor: `#FFFFFF`,
height: 256,
overflow: `hidden`,
}}>
<View style={{ marginTop: 20 }}>
<DateTimePicker
value={date}
mode="date"
is24Hour={true}
display="default"
onChange={onChange}
/>
<Text>hi</Text>
</View>
</View>
</TouchableOpacity>
</TouchableOpacity>
</View>
</Modal>
<View style={{ marginTop: 20 }}>
<DateTimePicker
testID="dateTimePicker"
value={date}
is24Hour={true}
display="default"
onChange={onChange}
/>
</View>
</View>
</TouchableOpacity>
</View>
);
}

Related

react native onPress not working in library in android

This is the start component and below the render function onPress function works fine.
import React, { useState, useEffect, useRef } from "react"
import {
StyleSheet,
Text,
View,
Image,
TouchableOpacity,
TextInput,
KeyboardAvoidingView,
Keyboard,
Button,
} from "react-native"
import BouncyCheckbox from "react-native-bouncy-checkbox"
import { SafeAreaView } from "react-native-safe-area-context"
import { ScrollView, TouchableWithoutFeedback } from "react-native-gesture-handler"
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view"
import RNPickerSelect from "react-native-picker-select"
import Animated from "react-native-reanimated"
import BottomSheet from "reanimated-bottom-sheet"
import EventBannerSheet from "./event-banner"
export const UserInfoPhone: React.FC = () => {
const userNumberFormRef = useRef<TextInput>()
const userNumberNextFormRef = useRef<TextInput>()
const userPhoneNumberFormRef = useRef<TextInput>()
const focusToNextForm = (nextForm: any) => {
nextForm.current.focus()
}
const EssentialAgreementContainer = ({ text }) => {
return (
<View style={styles.essentialAgreementContainer}>
<View style={styles.essentialSmallBox}>
<Text style={styles.essentialAgreementText}>[필수] {text}</Text>
<TouchableOpacity style={styles.okButton}>
<Text style={styles.okButtonTitle}>보기</Text>
</TouchableOpacity>
</View>
<BouncyCheckbox
size={17}
fillColor="lightgrey"
unfillColor="lightgrey"
iconStyle={{ borderColor: "lightgrey" }}
textStyle={{ fontFamily: "JosefinSans-Regular" }}
/>
</View>
)
}
return (
<>
<SafeAreaView style={styles.container}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<KeyboardAwareScrollView>
<Image source={require("./back.png")} style={styles.backButton} />
<View style={styles.viewTitle}>
<Text style={styles.title}>휴대폰으로</Text>
<Text style={styles.title}>간편 본인인증하세요.</Text>
</View>
<View style={styles.subTitleContainer}>
<Text style={styles.subTitle}>나중에 할게요</Text>
<TouchableOpacity style={styles.okButton}>
<Text style={styles.okButtonTitle}>확인</Text>
</TouchableOpacity>
</View>
<View style={[styles.agreementContainer, styles.shadowProps]}>
<View style={styles.conditionContainer}>
<Text style={styles.agreementTitle}>본인확인 서비스에 대해 모두 동의하기</Text>
<BouncyCheckbox
size={17}
fillColor="lightgrey"
unfillColor="lightgrey"
iconStyle={{ borderColor: "lightgrey" }}
textStyle={{ fontFamily: "JosefinSans-Regular" }}
/>
</View>
<View style={styles.contour}></View>
<EssentialAgreementContainer text="서비스 이용약관 동의" />
<EssentialAgreementContainer text="통신사 이용약관 동의" />
<EssentialAgreementContainer text="개인 정보 수집 및 이용 동의" />
<EssentialAgreementContainer text="개인 제어보 제공/위탁 동의" />
<EssentialAgreementContainer text="고유식별 정보 처리" />
</View>
<View style={styles.infoForms}>
<View style={styles.nameFormContainer}>
<Text style={styles.userInfo}>성명</Text>
<TextInput
style={styles.nameForm}
onSubmitEditing={() => {
focusToNextForm(userNumberFormRef)
}}
/>
</View>
<View style={styles.personNumberFormContainer}>
<Text style={styles.userInfo}>주민등록번호 (외국인등록번호)</Text>
<View style={styles.userNumberFormContainer}>
<TextInput
style={styles.userNumberForm}
maxLength={6}
placeholder="960101"
onSubmitEditing={() => {
focusToNextForm(userNumberNextFormRef)
}}
ref={userNumberFormRef}
/>
<Text style={{ fontSize: 20 }}>-</Text>
<TextInput
style={styles.userSecondNumberForm}
maxLength={1}
ref={userNumberNextFormRef}
onSubmitEditing={() => {
focusToNextForm(userPhoneNumberFormRef)
}}
/>
</View>
</View>
<View style={styles.phoneFormContainer}>
<Text style={styles.userInfo}>휴대폰번호</Text>
<View style={styles.phoneForms}>
<View style={styles.telecome}>
<RNPickerSelect
style={{ inputAndroid: { color: "black", padding: 0, height: 20 } }}
useNativeAndroidPickerStyle={false}
onValueChange={(value) => console.log(value)}
placeholder={{ label: "통신사" }}
items={[
{ label: "SKT", value: "SKT" },
{ label: "KT", value: "KT" },
{ label: "LG U+", value: "LG U+" },
{ label: "SKT알뜰폰", value: "SKT알뜰폰" },
{ label: "KT알뜰폰", value: "KT알뜰폰" },
{ label: "LG U+알뜰폰", value: "LG U+알뜰폰" },
]}
/>
</View>
<TextInput
style={styles.phoneForm}
placeholder="010-1234-5678"
ref={userPhoneNumberFormRef}
/>
</View>
</View>
</View>
<TouchableOpacity style={styles.certificationButton}>
<Text style={styles.certificationText}>인증하기</Text>
</TouchableOpacity>
</KeyboardAwareScrollView>
</TouchableWithoutFeedback>
</SafeAreaView>
<EventBannerSheet />
</>
)
}
and this is the EventBannerSheet Component, I got this BottomSheet library and wrote it, but the onPress function doesn't work here. Also I did it before using the Checkbox library but onValueChange also didn't work in android.
import React, { useRef } from "react"
import { StyleSheet, Text, View, Image, TouchableOpacity } from "react-native"
import BottomSheet from "reanimated-bottom-sheet"
const EventBannerSheet: React.FC = () => {
const sheetRef = useRef(null)
const consoleHello = () => {
console.log("helloooooooo!!!!")
}
const renderContent = () => (
<View style={styles.bottomSheet}>
<View style={styles.sheetTextContainer}>
<Text
style={styles.sheetText}
onPress={() => {
consoleHello()
}}
>
EVENT BANNER
</Text>
<Text style={styles.sheetText}>IMG</Text>
</View>
<View style={styles.sheetCloseContainer}>
<TouchableOpacity
onPress={() => {
console.log("helloMaster123")
}}
>
<Text style={{ color: "blue" }}>오늘 하루 보지않기</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => sheetRef.current.snapTo(2)}>
<Text>닫기</Text>
</TouchableOpacity>
</View>
</View>
)
return (
<>
<BottomSheet
initialSnap={1}
ref={sheetRef}
snapPoints={[450, 350, 0]}
borderRadius={10}
renderContent={renderContent}
/>
</>
)
}
and this is stylesheet of EventBannerSheet
const styles = StyleSheet.create({
bottomSheet: {
backgroundColor: "white",
padding: 25,
height: 440,
},
sheetTextContainer: {
height: 270,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#d3d3d3",
borderRadius: 10,
},
sheetText: {
fontSize: 30,
color: "white",
},
sheetCloseContainer: {
flexDirection: "row",
justifyContent: "space-between",
marginTop: 20,
},
})
<View style={styles.bottomSheet}>
<View style={styles.sheetTextContainer}>
<TouchableOpacity
style={styles.sheetText}
onPress={() => {
consoleHello()
}}
>
<Text style={{ color: "black" }}>EVENT BANNER</Text>
</TouchableOpacity>
<Text style={styles.sheetText}>IMG</Text>
</View>
<View style={styles.sheetCloseContainer}>
<TouchableOpacity
onPress={() => {
console.log("helloMaster123")
}}>
<Text style={{ color: "blue" }}>오늘 하루 보지않기</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => sheetRef.current.snapTo(2)}>
<Text>닫기</Text>
</TouchableOpacity>
</View>
</View>
Please try the above code. I have tested the code and touchable opacity is working fine without any issue. I have added a text color for EVENT BANNER text just to test. Let me know if you need any other help.
here is the config I've made to make it work on both iOS and Android with button and horizontal drag slider
<BottomSheet
initialSnap={1}
ref={sheetRef}
snapPoints={[450, 350, 0]}
borderRadius={10}
renderContent={renderContent}
enabledContentGestureInteraction={false}
enabledInnerScrolling={false}
enabledContentTapInteraction={false}
/>
I append three attributes so i solve this problem.
And the button inside the view use TouchableOpacity from RN for iOS and TouchableOpacity from react-native-gesture-handler for Android

Can't find variable: navigation - react-native - Tried trawling stack overflow can't find a fix

Having an issue with an app I'm developing,
Trying to use react navigation.
The app has a built in web-view and can be navigated (it's a wordpress site) - and the idea is when I hit the home button it should reset the app - I will be adding extra screens like settings etc
but I get: Can't find variable: navigation
Here is the code (I've omitted some sensitive data)
import React, {useState} from 'react'
import {
NativeModules,
SafeAreaView,
StyleSheet,
ActivityIndicator,
View,
Platform,
TouchableOpacity,
Text,
StatusBar,
Image
} from 'react-native';
import { WebView } from 'react-native-webview';
import BubblSdk from './BubblSdk';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
// import HomeScreen from './HomeScreen';
const HomeScreen = () => {
const secretCode = "***";
// BubblSdk.saveBubblId("TestDevice");
if (Platform.OS === 'android') {
BubblSdk.initialize('https://api.bubbl.tech/api/','******');
} else {
NativeModules.BubblSdk.saveActivatedPayloadTitle('Messages');
NativeModules.BubblSdk.initialize('https://api.bubbl.tech/api','*******');
}
messagesButtonHandler = () => {
proccessCode2();
if (Platform.OS === 'android') {
BubblSdk.payloadActivity();
} else {
NativeModules.BubblSdk.displayActivatedPayloads();
}
resetCodes();
}
dataButtonHandler = () => {
if (Platform.OS === 'android') {
BubblSdk.dataActivity();
} else {
NativeModules.BubblSdk.displayDataPayloads();
}
}
logButtonHandler = () => {
if (Platform.OS === 'android') {
BubblSdk.logsActivity();
} else {
NativeModules.BubblSdk.displayLogs();
}
}
mapButtonHandler = () => {
if (Platform.OS === 'android') {
BubblSdk.mapActivity();
}
}
var codes = "000";
var code1 = 0;
var code2 = 0;
var code3 = 0;
const [hide, setVisibile] = useState(Boolean);
const onPress1 = () => proccessCode1();
const onPress2 = () => proccessCode2();
const onPress3 = () => proccessCode3();
setCodes = () => {
codes = code1+ "" + code2 + code3;
console.log("aanchal codes: "+ codes);
}
setCodes();
resetCodes = () => {
code1 = 0;
code2 = 0;
code3 = 0;
setCodes();
setVisibile(false);
}
proccessCodes = () => {
setCodes();
if (codes == secretCode) {
setVisibile(true);
} else {
setVisibile(false);
}
}
proccessCode1 = () => {
code1 = code1 + 1;
proccessCodes();
}
proccessCode2 = () => {
code2 = code2 + 1;
proccessCodes();
}
proccessCode3 = () => {
code3 = code3 + 1;
proccessCodes();
}
const myScript = `
document.querySelector("#jp-post-flair").style.display="none";
document.querySelector("#actionbar").style.display="none";
document.querySelector("#colophon").style.display="none";
true; // note: this is required, or you'll sometimes get silent failures
`;
const messageImage = require('./images/Imatter-icons-13.png');
const homeImage = require('./images/Imatter-icons-14.png');
return (
<>
<StatusBar barStyle='dark-content' />
<SafeAreaView style={styles.flexContainer}>
<View style={{ flex: 1 }}>
<WebView
javaScriptEnabled={true}
domStorageEnabled={true}
injectedJavaScript={myScript}
mixedContentMode={'compatibility'}
source={{
uri: 'https://*******.wordpress.com/',
}}
onMessage={(event) => {}}
/>
</View>
<View style={styles.tabBarContainer}>
<View style={styles.column}>
<TouchableOpacity onPress={hide ? dataButtonHandler : onPress1}>
<Text style={hide ? styles.button : styles.codeButton}>{hide ? "Data" : "XXXXXX"}</Text>
</TouchableOpacity>
</View>
<View style={styles.column}>
<TouchableOpacity onPress={() => navigation.navigate('HomeScreen')}>
<Image style={styles.navImage} source={homeImage}/>
</TouchableOpacity>
</View>
<View style={styles.column}>
<TouchableOpacity onPress={messagesButtonHandler}>
<Image style={styles.navImage} source={messageImage}/>
</TouchableOpacity>
</View>
<View style={styles.column}>
<TouchableOpacity onPress={hide ? logButtonHandler : onPress3}>
<Text style={hide ? styles.button : styles.codeButton}>{hide ? "Logs" : "XXXXXX"}</Text>
</TouchableOpacity>
</View>
</View>
<View style={styles.tabBarContainer}>
<View style={styles.column}>
</View>
<View style={styles.column}>
<TouchableOpacity onPress={() => navigation.navigate('HomeScreen')}>
<Text style={styles.button}>Home</Text>
</TouchableOpacity>
</View>
<View style={styles.column}>
<TouchableOpacity onPress={messagesButtonHandler}>
<Text style={styles.button}>Messages</Text>
</TouchableOpacity>
</View>
<View style={styles.column}>
</View>
</View>
</SafeAreaView>
</>
);
};
const Stack = createNativeStackNavigator();
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} options={{headerShown: false}} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
flexContainer: {
flex: 1,
flexDirection: 'column'
},
tabBarContainer: {
padding: 10,
flexDirection: 'row',
justifyContent: 'space-around',
backgroundColor: '#fff'
},
navImage: {
justifyContent:'center',
alignItems: 'center'
},
column: {
width: '33%',
alignContent: "space-between",
justifyContent:'center',
alignItems: 'center'
},
button: {
textAlign: 'center',
color: 'black',
fontSize: 12
},
codeButton: {
opacity: 0,
fontSize: 12
}
});
export default App;
I am taking on a project - I'm still learning react native
firstly create folder in that folder create file HomeScreen.js paste ur all code on HomeScreen.js
const HomeScreen = ({navigation}) => { // your HomeScreen function code}
second import that file to the app.js
third on below code
return (
<>
<StatusBar barStyle='dark-content' />
<SafeAreaView style={styles.flexContainer}>
<View style={{ flex: 1 }}>
<WebView
javaScriptEnabled={true}
domStorageEnabled={true}
injectedJavaScript={myScript}
mixedContentMode={'compatibility'}
source={{
uri: 'https://*******.wordpress.com/',
}}
onMessage={(event) => {}}
/>
</View>
<View style={styles.tabBarContainer}>
<View style={styles.column}>
<TouchableOpacity onPress={hide ? dataButtonHandler : onPress1}>
<Text style={hide ? styles.button : styles.codeButton}>{hide ? "Data" : "XXXXXX"}</Text>
</TouchableOpacity>
</View>
<View style={styles.column}>
<TouchableOpacity onPress={() => navigation.navigate('Home')}>
// ur screen name should be used to navigate from one screen to another screen not a component
<Image style={styles.navImage} source={homeImage}/>
</TouchableOpacity>
</View>
<View style={styles.column}>
<TouchableOpacity onPress={messagesButtonHandler}>
<Image style={styles.navImage} source={messageImage}/>
</TouchableOpacity>
</View>
<View style={styles.column}>
<TouchableOpacity onPress={hide ? logButtonHandler : onPress3}>
<Text style={hide ? styles.button : styles.codeButton}>{hide ? "Logs" : "XXXXXX"}</Text>
</TouchableOpacity>
</View>
</View>
<View style={styles.tabBarContainer}>
<View style={styles.column}>
</View>
<View style={styles.column}>
<TouchableOpacity onPress={() => navigation.navigate('Home')}>
<Text style={styles.button}>Home</Text>
</TouchableOpacity>
</View>
<View style={styles.column}>
<TouchableOpacity onPress={messagesButtonHandler}>
<Text style={styles.button}>Messages</Text>
</TouchableOpacity>
</View>
<View style={styles.column}>
</View>
</View>
</SafeAreaView>
</>
);
};
const Stack = createNativeStackNavigator();
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} options={{headerShown: false}} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
flexContainer: {
flex: 1,
flexDirection: 'column'
},
tabBarContainer: {
padding: 10,
flexDirection: 'row',
justifyContent: 'space-around',
backgroundColor: '#fff'
},
navImage: {
justifyContent:'center',
alignItems: 'center'
},
column: {
width: '33%',
alignContent: "space-between",
justifyContent:'center',
alignItems: 'center'
},
button: {
textAlign: 'center',
color: 'black',
fontSize: 12
},
codeButton: {
opacity: 0,
fontSize: 12
}
});
export default App;
and another thing is that image source is working ? cause I am not seeing imported files at top ..thanks hope it will work.

onLongPress is not working in my application

maybe someone can help me with that. I don't know why my onLongPress is not working. After starting my application it shows errors like in the bellow link:
https://imageupload.io/i/0eEdzuD7CI
Please help me!
import React, { useState } from "react";
import {
View,
StyleSheet,
Text,
Image,[enter image description here][1]
TouchableHighLight,
TouchableOpacity,
Dimensions,
Button,
Modal
} from "react-native";
import Icon from "react-native-vector-icons/FontAwesome"
var { width } = Dimensions.get("window");
const ListItem = (props) => {
const [modalVisible, setModalVisible] = useState(false)
return (
<View>
<Modal animationType="fade" transparent={true} visible={modalVisible} onRequestClose={() => {
setModalVisible(false)
}}>
<View>
<View>
<TouchableHighLight
underlayColor="E8E8E8"
onPress={() => {
setModalVisible(false)
}}
style={{
alignSelf: "flex-end",
position: "absolute",
top: 5,
right: 10
}}
>
<Icon name="close" size={20} />
</TouchableHighLight>
<Button title="Edit"
onPress={() => [
props.navigation.navigate("Product Form"),
setModalVisible(false)
]}
/>
<Button title="Delete"
// delete
/>
</View>
</View>
</Modal>
<TouchableOpacity
onPress={() => {
props.navigation.navigate("Product Detail", { item: props })
}}
onLongPress={() => setModalVisible(true)}
style={[styles.container, {
backgroundColor: props.index % 2 == 0 ? "white" : "gainsboro"
}]}
>
<Image
source={{
uri: props.image
? props.image
: 'https://cdn.pixabay.com/photo/2012/04/01/17/29/box-23649_960_720.png'
}}
resizeMode="contain"
style={styles.image}
/>
<Text style={styles.item}>{props.brand}</Text>
<Text style={styles.item} numberOfLines={1} ellipsizeMode="tail">{props.name}</Text>
<Text style={styles.item} numberOfLines={1} ellipsizeMode="tail">{props.category.name}</Text>
<Text style={styles.item}>$ {props.price}</Text>
</TouchableOpacity>
</View>
)
}
const styles = StyleSheet.create({
container: {
flexDirection: "row",
padding: 5,
width: width
},
image: {
borderRadius: 50,
width: width / 6,
height: 20,
margin: 2
},
item: {
flexWrap: "wrap",
margin: 3,
width: width / 6
}
})
export default ListItem;

Text input becomes unusable after submitting data

I am implementing a page in my app that takes a user input and then searches a tv shows API for shows relating to what the user inputs. The form works, and data is returned succesfully, however once the search button has been clicked and the data has been returned, the search bar AND search button becomes unresponsive and will not bring up the keyboard. This was tested on a pixel 3 AVD, however on an iphone X using expo Go, the search button fully disapears from the page!
Here is the code:
import React, {useState} from 'react';
import { StyleSheet, Text, View, TextInput, TouchableOpacity, FlatList, ActivityIndicator, Image } from 'react-native';
import {AntDesign} from '#expo/vector-icons';
const ShowDisplay = ({navigation}) => {
const[text, changeText] = useState('');
const[data, setData] = useState([]);
const check = (item) => {
if(item.show.image){
return(
<Image source={{uri:item.show.image.medium}} style={{width:'100%', height: 200}} />
)
}else{
return(
<Text>Poo</Text>
)
}
}
const showfind = () =>{
fetch('https://api.tvmaze.com/search/shows?q=' + text)
.then((response)=> response.json())
.then((json)=> setData(json))
.catch((error)=>alert(error));
}
const showSearch = (text) =>{
showfind();
}
const changeHandler = (text) =>{
changeText(text)
}
console.log('text is currently '+ text)
return(
<>
<View style={styles.container}>
<View style = {styles.searchform}>
<TextInput
placeholder = 'Search for a show'
style = {styles.search}
onChangeText={text => changeHandler(text)}
/>
<TouchableOpacity onPress={() => showSearch(text)}>
<AntDesign name="search1" size={30} color='black' style = {{marginTop: 19, marginLeft: 15,}}/>
</TouchableOpacity>
</View>
</View>
<View>
{data? (<View style={styles.resultsContainer}>
<FlatList
style = {styles.list}
keyExtractor={(item, index)=> index.toString()}
numColumns= '3'
data={data}
renderItem={({item}) => (
<>
<TouchableOpacity style = {styles.show} onPress={() => navigation.navigate('toShow', {
id: item.show.id,
} )}>
<View style={styles.text}>
{check(item)}
</View>
</TouchableOpacity>
</>
)}
/>
</View>) : (<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#000"/>
</View>)}
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
},
search :{
paddingLeft: 15,
marginTop: 20,
borderRadius:30,
width: 200,
height: 30,
borderWidth: 1,
borderColor: '#000'
}, header : {
marginTop: 20,
fontSize: 30,
},
searchform:{
flexDirection: 'row',
},
show:{
width: '33.3%',
height: 200,
borderStyle: "solid",
borderColor: 'white',
borderWidth: 1,
},
list:{
marginTop: 70,
}
});
export default ShowDisplay;
I thought that maybe because the sumbit button runs a function, maybe the function never stops, and needs to be reset? When the sumbit button is pressed, it makes the call to the API.. I am unsure what is happening.
Looks like you're getting a weird side effect by using a Fragment (<></>) as the root view. The style is getting thrown off in certain circumstances.
Since you don't actually have a reason to use a Fragment as the root (your container view is the root element), removing it seemed to solve the issue. I also removed the unnecessary fragment you were using in the search button.
return(
<View style={styles.container}>
<View style = {styles.searchform}>
<TextInput
placeholder = 'Search for a show'
style = {styles.search}
onChangeText={text => changeHandler(text)}
/>
<TouchableOpacity onPress={() => showSearch(text)}>
<AntDesign name="search1" size={30} color='black' style = {{marginTop: 19, marginLeft: 15,}}/>
</TouchableOpacity>
</View>
<View>
{data? (<View style={styles.resultsContainer}>
<FlatList
style = {styles.list}
keyExtractor={(item, index)=> index.toString()}
numColumns= '3'
data={data}
renderItem={({item}) => (
<TouchableOpacity style = {styles.show} onPress={() =>
navigation.navigate('toShow', {
id: item.show.id,
} )}>
<View style={styles.text}>
{check(item)}
</View>
</TouchableOpacity>
)}
/>
</View>) : (<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#000"/>
</View>)}
</View>
</View>
);

TouchableOpacity is not working inside ScrollView

I am trying to implement A suggestion box for a text field. While entering input the suggestion box should appear just below to current text field and over the next input filed,
This suggestion should scroll after a maxHeight.
I am have implemented everything just the Touchable is not working inside ScrollView, if I replace ScrollView with simple View Touchable Works but the container will not scroll of course.
How to deal with this?
import React from 'react';
import {
View,
StatusBar,
ScrollView,
TextInput,
Text,
SafeAreaView,
TouchableOpacity,
} from 'react-native';
const TestScreen = () => {
const [val, setVal] = React.useState('');
const [show, setShow] = React.useState(false);
return (
<>
<SafeAreaView style={{flex: 1}}>
<TextInput
placeholder="Text"
value={val}
style={{zIndex: 1}}
onFocus={() => setShow(true)}
onBlur={() => setShow(false)}
onChangeText={t => {
setShow(true);
setVal(t);
}}
/>
<TextInput placeholder="Text" value={val} style={{zIndex: 1}} />
{show && (
<View style={{position: 'absolute', top: 50}}>
<ScrollView
style={{
elevation: 5,
zIndex: 5,
backgroundColor: 'white',
width: 100,
maxHeight: 50,
}}>
<TouchableOpacity onPress={() => setVal('Item1')}>
<Text>Item1</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => setVal('Item2')}>
<Text>Item2</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => setVal('Item3')}>
<Text>Item3</Text>
</TouchableOpacity>
</ScrollView>
</View>
)}
</SafeAreaView>
</>
);
};
export default TestScreen;
Please let me know where I am wrong.
So If you are looking for the answer to this problem.
Just remove the onBlur function props from TextField component.
Here you go, you got your own custom textfield suggestion box.
Here the solution code that helped to get this done. I still don't know it is the best idea but It worked for me atleast.
import React from 'react';
import {
View,
StatusBar,
ScrollView,
TextInput,
Text,
SafeAreaView,
TouchableOpacity,
} from 'react-native';
import {Button} from 'native-base';
const TestScreen = () => {
const [val, setVal] = React.useState('');
const [show, setShow] = React.useState(false);
return (
<>
<SafeAreaView style={{flex: 1}}>
<TouchableOpacity
style={{flex: 1}}
activeOpacity={1}
onPress={() => {
if (show) {
setShow(false);
}
}}>
<TextInput
placeholder="Text"
value={val}
style={{zIndex: 1}}
onFocus={() => setShow(true)}
onChangeText={t => {
setShow(true);
setVal(t);
}}
/>
<TextInput placeholder="Text" value={val} style={{zIndex: 1}} />
{show && (
<View
style={{
position: 'absolute',
top: 50,
}}>
<ScrollView
style={{
elevation: 5,
zIndex: 5,
backgroundColor: 'white',
width: 100,
maxHeight: 50,
}}>
<TouchableOpacity
onPress={() => {
setShow(false);
setVal('Item1');
}}>
<Text>Item1</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => setVal('Item2')}>
<Text>Item2</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => setVal('Item3')}>
<Text>Item3</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => setVal('Item4')}>
<Text>Item4</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => setVal('Item5')}>
<Text>Item5</Text>
</TouchableOpacity>
</ScrollView>
</View>
)}
</TouchableOpacity>
</SafeAreaView>
</>
);
};
export default TestScreen;