I'm building a react native app using the react-native-maps dependency but am unable to navigate to other screens using react-navigator onPress from within the MapView.
I would like to pass the { communityId: ${community._id} } object to view the unique community screen.
code:
import React, { Component } from 'react';
import { View, Image, StyleSheet, Vibration, TouchableOpacity, Text } from 'react-native';
import MapView, { Callout } from 'react-native-maps';
import { Marker } from 'react-native-maps';
class LogoTitle extends React.Component {
render() {
return (
<Image
source={require("./logo.png")}
style={{ width: 60, height: 30 }}
/>
);
}
}
class MapScreen extends Component {
constructor(props) {
super(props);
this.state = {
latitude: null,
longitude: null,
error: null,
communities: ""
};
}
componentDidMount() {
fetch("http://localhost:4000/community")
.then(res => res.json())
.then(res => {
this.setState({ communities: res });
});
Vibration.vibrate();
navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
});
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);
}
static navigationOptions = {
headerTitle: <LogoTitle />
};
navigateToView(viewName, { param: value }) {
console.log(viewName);
const { navigate } = this.props.navigation;
navigate(viewName, { param: value });
}
render() {
const LatLng = {
latitude: this.state.latitude,
longitude: this.state.longitude
}
let commcoords;
this.state.communities &&
(commcoords = this.state.communities.map((community, id) => {
let commlatlong;
commlatlong = {
latitude: community.location.lat,
longitude: community.location.long
};
return (
<Marker
key={id}
coordinate={commlatlong}
title={community.name}>
<Callout>
<TouchableOpacity
onPress={() => this.navigateToView("Community", { communityId: `${community._id}` })}
style={styles.communityButton}>
<Text style={styles.communityButtonText}>{community.name}</Text>
<Text style={styles.descButtonText}>{community.description}</Text>
</TouchableOpacity>
</Callout>
</Marker>
)
}))
return (
<View style={styles.container}>
{this.state.latitude &&
<MapView
style={styles.map}
initialRegion={{
latitude: this.state.latitude,
longitude: this.state.longitude,
latitudeDelta: 0.1011,
longitudeDelta: 0.1011,
}}>
<Marker
coordinate={LatLng}
title={`Latitude: ${this.state.latitude}`}
description={`Longitude: ${this.state.longitude}`}
pinColor='#000000'>
</Marker>
{commcoords}
</MapView>}
</View>
);
}
}
I have already attempted:
1) Using the normal navigation method.
onPress={() => this.props.navigation.navigate("Community", { communityId: `${community._id}` })}
2) Using alternate touch methods, buttons, touchable highlights, etc.
3) Attempted to console.log the triggered touch method using the remote debugger. The console.log was never triggered in the console.
navigateToView(viewName, { param: value }) {
console.log(viewName);
const { navigate } = this.props.navigation;
navigate(viewName, { param: value });
}
4) Researched and attempted solutions to no avail from the following stackoverflow links:
React Native - How to use React Navigation with React Native Maps?
React native maps click pin to take you to another screen
I would like to resolve this maps navigation issue to increase functionality in this native app. If there is an alternative method, I am open to any and all suggestions. Thank you.
I figured out how to trigger an the onpress event by using onCalloutPress in the Marker:
<Marker
key={id}
coordinate={commlatlong}
title={community.name}
onCalloutPress={() => this.props.navigation.navigate("Community", { communityId: `${community._id}` })}>
<Callout>
<TouchableOpacity
style={styles.communityButton}>
<Text style={styles.communityButtonText}>{community.name}</Text>
<Text style={styles.descButtonText}>{community.description}</Text>
</TouchableOpacity>
</Callout>
</Marker>
I am now able to navigate to show screens from the map. Thanks to this post:
Marker click event on react native maps not working in react ios
Additional source:
onCalloutPress Callback that is called when a callout is tapped by the user.
https://github.com/react-native-community/react-native-maps/blob/master/docs/mapview.md
Related
I'm using geolocation but i get the error: "undefined is not an object(evaluating 'navigator.geolocation.getCurrentPosition')
According to documentation, it's not necessary import Geolocation using react native 0.60 version or above.
version:
react-native-cli: 2.0.1
react-native: 0.60.4
import React, { Component } from "react";
import {
StyleSheet,
Text,
View,
Alert,
TouchableOpacity
} from "react-native";
export default class App extends Component {
state = {
location: null
};
findCoordinates = () => {
navigator.geolocation.getCurrentPosition(
position => {
const location = JSON.stringify(position);
this.setState({ location });
},
error => Alert.alert(error.message),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
};
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.findCoordinates}>
<Text style={styles.text}>Find My Coords?</Text>
<Text>Location: {this.state.location}</Text>
</TouchableOpacity>
</View>
);
}
}
i faced the same problem and i think that from 0.60 and above navigator it isn't supported so you have to use Geolocation
I am running this basic react native code for fetching latitude and longitude value on both android device and emulator but nowhere is the current lat/long value is being returned.
When run on emulator some value is being returned but its not the correct lat/long value, whereas on device value isn't even being return.Here is the code
import React, { Component } from 'react'
import { View, Text, Switch, StyleSheet, Button} from 'react-native'
import { createStackNavigator } from 'react-navigation';
class HomeScreen extends Component {
render() {
return (
<View style = {styles.container}>
<Button
title="Add New Outlet"
onPress={() => this.props.navigation.navigate('Details')}
/>
</View>
)
}
}
class DetailsScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
latitude: null,
longitude: null,
error: null,
};
}
componentDidMount() {
navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
});
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);
}
render(){
return(
<View style = {styles.container}>
<Text style = {styles.boldText}>
Latitude:
</Text>
<Text>
{this.state.latitude}
</Text>
<Text style = {styles.boldText}>
Longitude:
</Text>
<Text>
{this.state.longitude}
</Text>
</View>
)
}
}
const RootStack = createStackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
},
{
initialRouteName: 'Home',
}
);
export default class App extends React.Component {
render() {
return <RootStack />;
}
}
const styles = StyleSheet.create ({
container: {
flex: 1,
alignItems: 'center',
marginTop: 50
},
boldText: {
fontSize: 30,
color: 'red',
}
})
Please suggest any better alternatives..
For some reason navigator.geolocation is not working stable on Android devices, I changed getCurrentPosition to watchPosition and not used the third(geo_options) parameter. It worked for me.
componentDidMount() {
this.state.watchId = navigator.geolocation.watchPosition(
(position) => console.log(position),
(error) => console.log(error),
);
}
Also, you must clear watch and stop position observing when component unmounts.
componentWillUnmount() {
navigator.geolocation.clearWatch(this.state.watchId);
navigator.geolocation.stopObserving();
}
Fisrt, check android permissions:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Next:
componentDidMount() {
if (Platform.OS === "android") {
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
).then(granted => {
if (granted) this._getCurrentLocation();
});
} else {
this._getCurrentLocation();
}
}
Then:
_getCurrentLocation = () => {
navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
});
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);
}
I have a strange behavior and can not find a solution. In my React Native application I'm using the navigator.geolocation to determine the current position. My application is almost identical as the example in Facebook's Geolocation Code.
In the simulator my application works perfectly, but when I deploy it to my iphone the returning position (by getCurrentPosition and watchPosition) is not correctly. For example speed and heading is -1, accuracy is 65. Longitude and latitude seem to be valid, but not my real position (is in another country).
It does not matter whether I deploy the application via debug or release to the iphone, it always reacts same.
But if I start for example TomTom and put this application in the background, and then start my GeolocationExample application, everything works as it should.
My application I have created as follows:
react-native init GeolocationExample
And then I replaced the file index.ios.js with this code.
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
export default class GeolocationExample extends React.Component {
state = {
initialPosition: 'unknown',
lastPosition: 'unknown',
};
watchID: ?number = null;
componentDidMount() {
navigator.geolocation.getCurrentPosition(
(position) => {
var initialPosition = JSON.stringify(position);
this.setState({initialPosition});
},
(error) => alert(JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
this.watchID = navigator.geolocation.watchPosition((position) => {
var lastPosition = JSON.stringify(position);
this.setState({lastPosition});
});
}
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchID);
}
render() {
return (
<View style={styles.main}>
<Text>
<Text style={styles.title}>Initial position: </Text>
{this.state.initialPosition}
</Text>
<Text>
<Text style={styles.title}>Current position: </Text>
{this.state.lastPosition}
</Text>
</View>
);
}
}
var styles = StyleSheet.create({
main: {
margin: 30
},
title: {
fontWeight: '500',
},
});
AppRegistry.registerComponent('GeolocationExample', () => GeolocationExample);
1st option : add parameter
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000, accuracy:10 //ten meters not in the document}
2nd option : set line 28
#define RCT_DEFAULT_LOCATION_ACCURACY kCLLocationAccuracyBest //default was kCLLocationAccuracyHundredMeters
I am trying to get the longitude and langtitude but it seems like I can't access it from the default geolocation json object that I get.
I followed this example form the docs and it works great but I only need the long & lat so I am trying to pick it out like this:
const LATITUDE = 19.0760;
const LONGITUDE = 72.8777;
class Map extends Component {
state = {
region: {
latitude: LATITUDE,
longitude: LONGITUDE
},
};
watchID: ?number = null;
componentDidMount() {
navigator.geolocation.getCurrentPosition(
(position) => {
var initialPosition = JSON.stringify(position);
this.setState({
initialRegion: {
latitude: initialPosition.coords.latitude,
longitude: initialPosition.coords.longitude,
}
});
},
(error) => alert(JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
this.watchID = navigator.geolocation.watchPosition((position) => {
var lastPosition = JSON.stringify(position);
this.setState({
lastRegion: {
latitude: lastPosition.coords.latitude,
longitude: lastPosition.coords.longitude,
}
});
});
}
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchID);
}
render() {
return (
<View>
<Text>
<Text style={styles.title}>Initial position: </Text>
{this.state.initialRegion}
</Text>
<Text>
<Text style={styles.title}>Current position: </Text>
{this.state.lastRegion}
</Text>
</View>
);
}
}
Eventualy I want to do render something like this:
render() {
return (
<MapView
style={ styles.map }
initialRegion={{
latitude: {this.state.lat},
longitude:{this.state.long},
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
);
}
Try this:
import React, { Component } from 'react';
import {
MapView,
StyleSheet,
View,
} from 'react-native';
var Dimensions = require('Dimensions'),
windowSize = Dimensions.get('window'),
Screen = require('Dimensions').get('window'),
NavigationBar = require('react-native-navbar');
var regionText = {
latitude: '0',
longitude: '0',
latitudeDelta: '0',
longitudeDelta: '0',
};
class LocateMap extends Component {
createAnnotation(longitude, latitude) {
return {
longitude,
latitude,
draggable: true,
onDragStateChange: (event) => {
if (event.state === 'starting') {
this.setState({
annotations: [this.createAnnotation(event.longitude, event.latitude)],
});
}
},
};
}
constructor(props) {
super(props);
this.state = {
isFirstLoad: true,
annotations: [],
mapRegion: undefined,
};
}
render() {
if (this.state.isFirstLoad) {
var onRegionChangeComplete = (region) => {
//When the MapView loads for the first time, we can create the annotation at the
//region that was loaded.
this.setState({
isFirstLoad: true,
annotations: [this.createAnnotation(region.longitude, region.latitude)],
});
};
}
const rightButtonConfig = {
title: 'Locate',
tintColor:'#ffffff',
handler: () => {
this.props.data.getMapPosition(this.state.annotations[0].longitude, this.state.annotations[0].latitude);
this.props.navigator.pop();
},
};
return (
<View style={{flex:1}}>
<MapView
style={styles.map}
onRegionChangeComplete={onRegionChangeComplete}
region={this.state.mapRegion}
annotations={this.state.annotations}
zoomEnabled={true}
showsUserLocation={true}
/>
</View>
);
}
};
var styles = StyleSheet.create({
map: {
height: Screen.height,
width: Screen.width
}
});
module.exports= LocateMap;
I need to access my location from GPS. So, i import geolocation to project.
first, I create following like this (install react native map, already link)
and I just already add NSLocationWhenInUseUsageDescription in my Xcode
also, I just already libRCTGeolocation.a in my Xcode
then, I just read map view in mapview from Airbnb. tell me to set showUserLocation set it to "true". when set true will ask user to access
location.
reference: https://github.com/airbnb/react-native-maps/blob/master/docs/mapview.md
finally, That is not ask anything to access
location. so, I don't know why. I can't find my current location.
and this is my picture step by step that I describe from begin
http://imgur.com/a/5TJZa
I will show you my code.
Route.js
import React, { Component, PropTypes } from 'react';
import {
StyleSheet,
View,
Text,
Image,
Dimensions,
} from 'react-native';
import MapView from 'react-native-maps';
var {height, width} = Dimensions.get('window');
export default class Route extends Component {
constructor(props){
super(props);
this.state = {
region: {
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}
};
this.onRegionChange = this.onRegionChange.bind(this);
}
onRegionChange(region) {
this.setState({ region });
}
render() {
return (
<View style={styles.container}>
<MapView style={styles.map}
mapType="standard"
showsUserLocation={true}
followsUserLocation={true}
showsCompass={false}
showsPointOfInterest={false}
region={this.state.region}
onRegionChange={this.onRegionChange}
/>
<View style={styles.container}>
<Text>
Latitude: {this.state.region.latitude}{'\n'}
Longitude: {this.state.region.longitude}{'\n'}
LatitudeDelta: {this.state.region.latitudeDelta}{'\n'}
LongitudeDelta: {this.state.region.longitudeDelta}
</Text>
</View>
</View>
);
}
}
Route.navigationOptions = { //this define from App.js option in SecondScreen
title: 'Route', //name top of StackNavigator
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
image: {
width: 200,
height: 200,
},
text: {
color: 'white',
fontWeight: 'bold',
backgroundColor: 'transparent',
marginTop: 20,
},
map: {
width: width,
height: height*2/3
}
});
In the iOS simulator it reads a fake location. Set a custom location using Debug > Location > Custom Location... in the simulator menu.
If you run it on a real device you will get the real location. If you continue to use the simulator you can just put your current location using the Custom Location menu. You can get your location a number of ways, including this: http://mylocation.org/.