I have a structure like this:
<View style={container}>
<View style={first}></View>
<View style={second}><View>
<View style={third}</View>
</View>
The container pretty much fills the whole screen.
When the user touches the container and moves the finger around without lifting the finger, I would like to know which View the finger is currently placed at.
Use TouchableWithoutFeedback to wrap around your views, and then you can call the onPressIn function to detect touch event.
You cannot detect the touched view unless and until you don't have any touch event on it.
To do that you can use TouchableOpacity (respond to the press and have visual feedback when touched.) or TouchableWithoutFeedback (it won't show any visual feedback when touched)
Below is the sample example as required:
import React, { Component } from 'react'
import {
TouchableOpacity,
View
} from 'react-native'
export default class SampleComponent extends Component {
constructor(props) {
super(props)
}
_onPressView = (viewName) => {
console.log("Tapped View ===> ", viewName)
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={() => this._onPressView("FirstView")}>
<View style={styles.first}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this._onPressView("SecondView")}>
<View style={styles.second}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this._onPressView("ThirdView")}>
<View style={styles.third}/>
</TouchableOpacity>
</View>
);
}
}
Related
I'm trying to use a touchablehighlight component and when I press it, nothing happens. So I changed it to a button and added a console log and still, react native won't register the press.
I'm using expo and I'm relatively new to react native.
Please tell me what I'm doing wrong
import React, { useState } from "react";
import {
Button,
Modal,
StyleSheet,
Text,
TouchableHighlight,
View,
} from "react-native";
const customPicker = (props) => {
const [selectedNumber, setSelectedNumber] = useState(props.pickerValues[0]);
const [pickerDisplayed, setPickerDisplayed] = useState(false);
function changeSelectedNumber(value) {
setSelectedNumber(value);
setPickerDisplayed(false);
}
const touchableHighlightcomponent = props.pickerValues.map((value, index) => (
<TouchableHighlight
style={styles.th}
onPress={() => changeSelectedNumber({ value })}
key={index}
>
<Text>{value}</Text>
</TouchableHighlight>
));
return (
<View>
<Button onPress={() => console.log("pressed")} title="one"></Button>
{/* <TouchableHighlight style={styles.input} onPress={() => this.console.log("pressed")}>
<Text>{selectedNumber}</Text>
</TouchableHighlight> */}
<Modal visible={() => pickerDisplayed} transparent={true}>
<View style={styles.picker}>
<View style={styles.pickerItems}>
<Text>Please select a value</Text>
{touchableHighlightcomponent}
</View>
</View>
</Modal>
</View>
);
};
I have discovered the problem.
It's a bug with the iOS simulator, it doesn't register button pushes.
To fix: Simply restart the iOS simulator
In my react native app I have a modal
Inside this Modal I have a FlatList
<Modal animationType="slide" transparent={false} visible={this.state.typeVisible}>
<View style={styles.modalView}>
<View style={styles.modal_header}>
<Text style={styles.modal_header_text}>Select Type</Text>
<Ionicons name="ios-close" size={48} style={styles.modal_header_close} onPress={this.toggleType} />
</View>
<View style={styles.modal_list_container}>
<FlatList
keyExtractor={item => item.key}
data={[{ key: "Call Out" }, { key: "Call" }, { key: "Delivery" }, { key: "Dealt By Caller" }]}
renderItem={({ item }) => (
//this.handleType(item.key)
<TouchableWithoutFeedback
onPress={() => alert("Working!!") }
>
<View>
<Text style={styles.modal_list_item}>{item.key}</Text>
</View>
</TouchableWithoutFeedback>
)}
/>
</View>
</View>
</Modal>
On IOS each of the items in the FlatList are clickable and the onPress will trigger the "Working!!" alert.
However the onPress is not working on Android. If I take the Flatlist outside the Modal the onPress will trigger the alert fine.
Can anyone tell me what I might be doing wrong in trying to get it working inside the Modal on Android?
Ps: I have also tried TouchableOpacity in place of TouchableWithoutFeedback but to no avail
Thanks
I assume you are importing TouchableOpacity (TouchableWithoutFeedback) from "react-native-gesture-handler"
I don't know why, but you need to import it from "react-native"
import { TouchableOpacity, TouchableWithoutFeedback } from 'react-native';
Hope that would help
I have created modal in react native. I have added filter option icon in top right corner now when the user clicks on it should open the modal. How can I do that ? I have added Options icon in navigation.js but now how to connect it with modal component ?
In code below setModalVisible is available in filteroptions.js and not in navigation.js
Code:
navigation.js:
Updates: {
screen: UpdatesScreen,
navigationOptions: ({ navigation }) => ({
headerTitle: 'Myapp',
headerRight:<TouchableOpacity onPress={() => {this.setModalVisible(true);}}>
<MenuIcon style={{paddingLeft: 10, paddingRight: 15}} name="md-options" size={25} color="white"/>
</TouchableOpacity>,
})
},
filteroptions.js:
import React, {Component} from 'react';
import {Modal, Text, TouchableHighlight, View, Alert} from 'react-native';
export default class FilteroptionsModel extends Component {
state = {
modalVisible: false,
};
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
render() {
return (
<View style={{marginTop: 22}}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<View style={{marginTop: 22}}>
<View>
<TouchableHighlight
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
</View>
);
}
}
When user clicks on filter button in top right corner (see screenshot) he should be able to see the box modal on screen:
Since it is a modal you don't necessarily need to add it to the navigation. You can just include it in your page and initially have it be invisible, then when the user clicks your button you can make the modal visible. But if you want to add it to the navigation why not just add like any other component. However, adding it to the navigation will take you to another page when you navigate to the component. Of course you can add a nested navigator to work around that, but I think it adds unnecessary complexity.
Update
You will first declare a Header component.
export default class MyHeader extends React.PureComponent {
render() {
<View>
<View>...Your left Icon here</View>
<View>...Your Title here</View>
<View>...Your right Icon Here</View>
</View>
}
}
Then in your page you will render this component first, pass as props your handlers and then render the rest of the page.
export default class MyPage extends React.PureComponent {
yourRigthHandler = () => {
this.setState({modaVisible: true});
}
yourLeftHandler = () => {....}
render() {
<View>
<MyHeader
LeftHandler={yourLeftHandler}
LeftHandler={yourRigthHandler}>
....
</MyHeader>
</View>
}
}
inside the handlers you can call the navigation functions to navigate to another page or change the components state to make the moda visible.The handlers will be passed as props to your header and you will add them as onPress handlers to your buttons.
I've recently been learning React Native but haven't really found a way to manipulate the DOM.
I've been trying to make it so that if I click on the TouchableHighlight my Image moves down a couple of px, but I have not managed to get it to move yet and I honestly don't know how to go from here.
My onclick function works since it does return the log every time the button is clicked.
As of now I have this:
export default class MainBody extends Component {
onclick = () => {
console.log('On click works')
};
render() {
return (
<ScrollView showsHorizontalScrollIndicator={false} style={Style.horList} horizontal={true}>
<View >
{/*i need to move this Image down!*/}
<Image source={require("./img/example.png")}/>
<View>
<Text style={Style.peopleInvited}>This is text</Text>
</View>
{/*When clicked on this touchable highlight!*/}
<TouchableHighlight onPress={this.onclick}}>
<Image source={require('./img/moveImg.png')}/>
</TouchableHighlight>
</View>
</ScrollView>
}
If someone could help me get past this that would be greatly appreciated.
Thank you so much for your time!
There are many ways to do this, but perhaps the easiest way would be using states.
class MainBody extends Component {
constructor(props) {
super(props);
this.state = {
top: 0 // Initial value
};
}
onclick = () => {
console.log('On click works')
this.setState( { top: this.state.top + 5 }) // 5 is value of change.
};
render() {
return (
<ScrollView showsHorizontalScrollIndicator={false} horizontal={true}>
<View >
{/*i need to move this Image down!*/}
<Image style={{top: this.state.top}}source={require("./img/example.png")}/>
<View>
<Text>This is text</Text>
</View>
{/*When clicked on this touchable highlight!*/}
<TouchableHighlight onPress={this.onclick}>
<Image source={require("./img/moveImg.png")}/>
</TouchableHighlight>
</View>
</ScrollView>
);
}
}
I've written a click handler to resolve a download button to the google play store URL.
The problem is that when the page loads, the URL is immediately visited.
The click handler is nested inside an onPress attribute, and I don't press anything, so I'm struggling to understand why this would be happening.
Any help would be appreciated!
OpenURL.js:
'use strict';
import React, {
Component,
PropTypes,
Linking,
StyleSheet,
Text,
TouchableNativeFeedback,
TouchableHighlight,
View
} from 'react-native';
class OpenURLButton extends Component {
constructor(props) {
super(props);
}
handleClick(url) {
console.log(url);
console.log('handling click! this is : ');
console.dir(this);
Linking.canOpenURL(this.props.url).then(supported => {
if (supported) {
Linking.openURL(this.props.url);
} else {
console.log('Don\'t know how to open URI: ' + this.props.url);
}
});
}
render() {
console.log('logging "this" inside render inside OpenURL.js:');
console.dir(this);
return (
<TouchableHighlight onPress={this.handleClick(this.props.appStoreUrl)}>
<Text>Download {this.props.appStoreUrl}</Text>
</TouchableHighlight>
);
}
}
OpenURLButton.propTypes = {
url: React.PropTypes.string,
}
export default OpenURLButton;
Inventory.js:
<ScrollView>
<View style={styles.ImageContainer}>
<Image style={styles.ImageBanner} source={{uri: selectedInventory.bannerImage}} />
</View>
<View style={styles.ListGridItemCaption}>
<Image style={[styles.ImageThumb, styles.ImageGridThumb]} source={{uri: selectedInventory.thumbImage}} />
<Text style={styles.Text} key="header">{name}</Text>
</View>
<View>
<Text>{selectedInventory.description}</Text>
<OpenURLButton url={selectedInventory.appStoreUrl}/>
</View>
</ScrollView>
Change:
<TouchableHighlight onPress={this.handleClick(this.props.appStoreUrl)}>
<Text>Download {this.props.appStoreUrl}</Text>
</TouchableHighlight>
To:
<TouchableHighlight onPress={() => {this.handleClick(this.props.appStoreUrl)}}>
<Text>Download {this.props.appStoreUrl}</Text>
</TouchableHighlight>
With the change you are creating anonymous function that are calling on "your" method. This will work.