With this code how would I add a second or multiple panresponders that can be moved independently of each other? If I use the same panresponder instance and code they move together as one. I want to know how to have several independently draggable panresponders.
'use strict';
var React = require('react-native');
var {
PanResponder,
StyleSheet,
View,
processColor,
} = React;
var CIRCLE_SIZE = 80;
var CIRCLE_COLOR = 'blue';
var CIRCLE_HIGHLIGHT_COLOR = 'green';
var PanResponderExample = React.createClass({
statics: {
title: 'PanResponder Sample',
description: 'Shows the use of PanResponder to provide basic gesture handling.',
},
_panResponder: {},
_previousLeft: 0,
_previousTop: 0,
_circleStyles: {},
circle: (null : ?{ setNativeProps(props: Object): void }),
componentWillMount: function() {
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,
onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder,
onPanResponderGrant: this._handlePanResponderGrant,
onPanResponderMove: this._handlePanResponderMove,
onPanResponderRelease: this._handlePanResponderEnd,
onPanResponderTerminate: this._handlePanResponderEnd,
});
this._previousLeft = 20;
this._previousTop = 84;
this._circleStyles = {
style: {
left: this._previousLeft,
top: this._previousTop
}
};
},
componentDidMount: function() {
this._updatePosition();
},
render: function() {
return (
<View
style={styles.container}>
<View
ref={(circle) => {
this.circle = circle;
}}
style={styles.circle}
{...this._panResponder.panHandlers}
/>
</View>
);
},
_highlight: function() {
const circle = this.circle;
circle && circle.setNativeProps({
style: {
backgroundColor: processColor(CIRCLE_HIGHLIGHT_COLOR)
}
});
},
_unHighlight: function() {
const circle = this.circle;
circle && circle.setNativeProps({
style: {
backgroundColor: processColor(CIRCLE_COLOR)
}
});
},
_updatePosition: function() {
this.circle && this.circle.setNativeProps(this._circleStyles);
},
_handleStartShouldSetPanResponder: function(e: Object, gestureState: Object): boolean {
// Should we become active when the user presses down on the circle?
return true;
},
_handleMoveShouldSetPanResponder: function(e: Object, gestureState: Object): boolean {
// Should we become active when the user moves a touch over the circle?
return true;
},
_handlePanResponderGrant: function(e: Object, gestureState: Object) {
this._highlight();
},
_handlePanResponderMove: function(e: Object, gestureState: Object) {
this._circleStyles.style.left = this._previousLeft + gestureState.dx;
this._circleStyles.style.top = this._previousTop + gestureState.dy;
this._updatePosition();
},
_handlePanResponderEnd: function(e: Object, gestureState: Object) {
this._unHighlight();
this._previousLeft += gestureState.dx;
this._previousTop += gestureState.dy;
},
});
var styles = StyleSheet.create({
circle: {
width: CIRCLE_SIZE,
height: CIRCLE_SIZE,
borderRadius: CIRCLE_SIZE / 2,
backgroundColor: CIRCLE_COLOR,
position: 'absolute',
left: 0,
top: 0,
},
container: {
flex: 1,
paddingTop: 64,
},
});
module.exports = PanResponderExample;
You can use an array of PanResponders, created like so:
this._panResponders = yourObjectsArray.map((_, index) => (
PanResponder.create({
onMoveShouldSetPanResponder: () => true,
...
})
));
yourObjectsArray is an array that you use for creating as many panResponders as you want, I imagine each object in that array will correspond to a data instance of whatever data structure you use to create the moveable Views.
Then to actually use it in your View:
render: function() {
return yourObjectsArray.map((_, index) => (
<View
style={styles.container}>
<View
... some stuff here ...
{...this._panResponders[index].panHandlers}
/>
</View>
)
};
Related
I'm using highchart map, that displays the USA state and its counties, but I want to show all cities of the selected state and when someone clicks on the city map it will display pop up model
I want to display all cities of the selected state and when someone clicks on the city map it will display a pop-up model.
The code I'm using right now
<div id="container"></div>
<script>
const drilldown = async function (e) {
// console.log('hover key', e.point.drilldown)
if (!e.seriesOptions) {
const chart = this,
mapKey = `countries/us/${e.point.drilldown}-all`;
// Handle error, the timeout is cleared on success
let fail = setTimeout(() => {
if (!Highcharts.maps[mapKey]) {
chart.showLoading(`<i class="icon-frown"></i> Failed loading ${e.point.name}`);
fail = setTimeout(() => {
chart.hideLoading();
}, 1000);
}
}, 3000);
// Show the Font Awesome spinner
chart.showLoading('<i class="icon-spinner icon-spin icon-3x"></i>');
var topology = await
fetch(https://code.highcharts.com/mapdata/${mapKey}.topo.json)
.then(response => response.json());
// Load the drilldown map
// const topology = await fetch(`https://code.highcharts.com/mapdata/${mapKey}.topo.json`)
// .then(response => response.json());
const data = Highcharts.geojson(topology);
// Set a non-random bogus value
data.forEach((d, i) => {
d.value = i;
console.log('data',d)
});
// Apply the recommended map view if any
chart.mapView.update(
Highcharts.merge(
{ insets: undefined },
topology.objects.default['hc-recommended-mapview']
),
false
);
// Hide loading and add series
chart.hideLoading();
clearTimeout(fail);
chart.addSeriesAsDrilldown(e.point, {
name: e.point.name,
data,
dataLabels: {
enabled: true,
format: '{point.name}'
}
});
}
};
// On drill up, reset to the top-level map view
const drillup = function (e) {
if (e.seriesOptions.custom && e.seriesOptions.custom.mapView) {
e.target.mapView.update(
Highcharts.merge(
{ insets: undefined },
e.seriesOptions.custom.mapView
),
false
);
}
};
(async () => {
const topology = await fetch(
'https://code.highcharts.com/mapdata/countries/us/us-all.topo.json'
).then(response => response.json());
const data = Highcharts.geojson(topology);
const mapView = topology.objects.default['hc-recommended-mapview'];
// Set drilldown pointers
data.forEach((d, i) => {
d.drilldown = d.properties['hc-key'];
d.value = i; // Non-random bogus data
});
// Instantiate the map
Highcharts.mapChart('container', {
chart: {
events: {
drilldown,
drillup,
thrilup
}
},
title: {
text: 'Highcharts Map Drilldown'
},
colorAxis: {
min: 0,
minColor: '#E6E7E8',
maxColor: '#005645'
},
mapView,
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
plotOptions: {
map: {
states: {
hover: {
color: '#EEDD66'
}
}
}
},
series: [{
data,
name: 'USA',
dataLabels: {
enabled: true,
format: '{point.properties.postal-code}'
},
custom: {
mapView
}
}],
drilldown: {
activeDataLabelStyle: {
color: '#FFFFFF',
textDecoration: 'none',
textOutline: '1px #000000'
},
drillUpButton: {
relativeTo: 'spacingBox',
position: {
x: 0,
y: 60
}
}
},
thrilup: {
activeDataLabelStyle: {
color: '#FFFFFF',
textDecoration: 'none',
textOutline: '1px #000000'
},
drillUpButton: {
relativeTo: 'spacingBox',
position: {
x: 0,
y: 60
}
}
}
});
})();
I am using a Konva stage to hover over floor areas on browser (see running Next app here https://www.planpoint.io/themes/modern-1) and it works great on any device, except on iPhones. After some touches on the floors areas, they suddenly dissapear as if the canvas element would no longer be there. Has tested it with Safari and Chrome on iOS16.2 . The only difference for mobile devices is the use of touchstart, touchend events, instead of mouseover, mouseout events.
Here is the code for rendering the canvas component and background image
import { useEffect, useState, useRef, useLayoutEffect } from 'react'
import Image from 'next/image'
import Konva from 'konva';
import i18nService from '../../../helpers/i18nService'
import useWindowSize from '../../../hooks/useWindowSize'
export default function InteractiveCanvas(props) {
const [showCanvas, setShowCanvas] = useState(false);
const [placeholderWidth, setPlaceholderWidth] = useState(1);
const [placeholderHeight, setPlaceholderHeight] = useState(1);
const [width, height] = useWindowSize();
const canvasAreaRef = useRef(null)
const canvasPlaceholderRef = useRef()
let stage, shapesLayer, tooltipLayer;
useEffect(() => {
if (showCanvas) {
props.loaded() // Canvas has loaded
}
},[showCanvas])
useLayoutEffect(() => { initializeCanvas() });
useEffect(() => { initializeCanvas() }, [width, height]);
function initializeCanvas() {
if (!canvasPlaceholderRef.current || !canvasPlaceholderRef.current.clientWidth || !canvasPlaceholderRef.current.clientHeight || !canvasPlaceholderRef.current.clientWidth) {
// wait until the placeholder is available
setTimeout(function() { initializeCanvas() }, 1000)
} else if (canvasPlaceholderRef.current) {
// initialize placeholder
setPlaceholderWidth(canvasAreaRef.current.clientWidth)
setPlaceholderHeight(canvasPlaceholderRef.current.clientHeight)
// initialize konva
let width = canvasPlaceholderRef.current.clientWidth;
let height = canvasPlaceholderRef.current.clientHeight;
stage = new Konva.Stage({
container: props.konvaContainer,
width: width,
height: height,
name: 'stage'
});
shapesLayer = new Konva.Layer({ name: 'shapes' });
tooltipLayer = new Konva.Layer({ name: 'tooltips' });
let tooltip = new Konva.Label({
opacity: 1,
visible: false,
listening: false,
name: 'label'
});
tooltip.add(
new Konva.Tag({
fill: '#313131',
pointerDirection: 'down',
pointerWidth: 20,
pointerHeight: 10,
cornerRadius: 4,
lineJoin: 'round',
shadowColor: 'black',
shadowBlur: 10,
shadowOffsetX: 10,
shadowOffsetY: 10,
shadowOpacity: 0.25,
name: 'tag'
})
);
tooltip.add(
new Konva.Text({
text: '',
align: 'center',
lineHeight: 2,
fontFamily: 'Inter',
fontSize: 13,
padding: 5,
fill: 'white',
name: 'tag',
width: props.wideTooltip ? 160 : 80
})
);
tooltipLayer.add(tooltip);
let areas = getData();
// draw areas
for (let key in areas) {
let area = areas[key];
let shape = new Konva.Line({
stroke: 'white',
strokeWidth: 2,
points: area.points,
fill: area.color,
opacity: area.disabled || area.visible ? 1 : key === props.selected?.name ? 1 : 0, // Keep the selected floor/unit highlight shape with opacity 1 after render
disabled: area.disabled,
closed: true,
target: area.target,
key: key,
subline: area.subline,
perfectDrawEnabled: false,
name: 'line',
cursor: 'pointer'
});
let group = new Konva.Group({name: 'group'})
shapesLayer.add(group);
group.add(shape);
}
stage.add(shapesLayer);
stage.add(tooltipLayer);
stage.on('mouseover touchstart', function (evt) {
if (evt && evt.target) {
let shape = evt.target;
if (shape && !shape.attrs.editable) {
shape.opacity(1);
shapesLayer.draw();
if (evt.type === 'touchstart' && shape.attrs.name === 'line') props.onClick(shape.attrs.target)
}
}
});
stage.on('mouseout touchend', function (evt) {
if (evt && evt.target) {
let shape = evt.target;
if(shape.attrs.name === 'stage' || shape.attrs.target === props.selected?._id) return // Do nothing unless it is a different line shape
if (shape && !shape.attrs.editable) {
shape.opacity(shape.attrs.disabled || shape.attrs.visible ? 1 : 0);
shapesLayer.draw();
tooltip.hide();
tooltipLayer.draw();
}
}
});
stage.on('mousemove', function(evt) {
let shape = evt.target;
if (shape) {
let mousePos = stage.getPointerPosition();
let x = mousePos.x;
let y = mousePos.y - 5;
updateTooltip(tooltip, x, y, shape.attrs.key, shape.attrs.subline);
tooltipLayer.draw();
}
});
stage.on('click tap', function(evt) {
let shape = evt.target;
if(shape.attrs.name === 'stage' || shape.attrs.target === props.selected?._id) return // Do nothing unless it is a different line shape
if (shape && shape.attrs.target) props.onClick(shape.attrs.target)
})
setTimeout(() => {
setShowCanvas(true)
shapesLayer.draw();
tooltipLayer.draw();
}, 100)
}
}
function getData() {
let areas = {}
function transformPoints(points) {
const c = JSON.parse(points || '[]')
return c.map((e, i) => (i % 2) ? (placeholderWidth * e) : placeholderHeight * e)
}
// add inactive paths
for (let p of props.inactivePaths) {
let newData = {
target: p.target,
color: p.disabled ? (props.disabledColor || '#E1171799') : props.accentColor || 'rgba(15, 33, 49, 0.65)',
points: transformPoints(p.path),
visible: p.visible,
disabled: p.disabled
}
if (props.project && props.project.showFloorOverview) {
let availableUnits = p.units.filter(u => u.availability.toLowerCase() === 'available').length
newData.subline = props.project.showFloorOverview ? `${availableUnits} ${i18nService.i18n(props.locale, "canvas.unitsavailable")}` : ''
}
areas[p.title] = newData
}
return areas;
}
function updateTooltip(tooltip, x, y, text, subline) {
const conditionalSubline = subline ? `\n${subline}` : ''
tooltip.children[1].text(text+conditionalSubline);
// tooltip.getText().text(text);
tooltip.position({ x: x, y: y });
if (text) tooltip.show();
};
return (
<div className={props.styles.canvasContainer}>
<img
className={props.styles.canvasImgPlaceholder}
ref={canvasPlaceholderRef}
alt='Canvas Placeholder'
src={props.background}
/>
<div className={props.styles.canvasPlaceholderBox} data-hide={showCanvas}>
<Image src="/images/planpoint_icon.svg" width={200} height={200} alt="" />
</div>
<div
className={props.styles.canvasKonvaContainer}
id={props.konvaContainer}
ref={canvasAreaRef}
data-hide={!showCanvas}
style={{backgroundImage: `url('${props.background}')`}}
>
</div>
</div>
)
}
I want to add tabs at the bottom of my home screen but I don't manage how to do it.
I want two tabs like "Map" (for my homepage) and "Settings". I don't know how to create that, I tried to add some codes inside but it's not working. Do you have ideas of what I'm doing wrong?
Do I need to add these codes inside ?
class HomeScreen extends React.Component {
render() {
return (
class SettingsScreen extends React.Component {
render() {
return (
I also tried to add this code at the bottom:
const TabNavigator = createBottomTabNavigator({
MAP: { screen: HomeScreen },
SETTINGS: { screen: SettingsScreen },
});
export default createAppContainer(TabNavigator);
Here is my code:
import React, { Component } from 'react';
import { StyleSheet, Text, View, Animated, Image, Dimensions } from "react-native";
import { Components, MapView } from 'expo';
const Images = [
{ uri: "https://images.unsplash.com/photo-1555706655-6dd427c11735?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80" },
{ uri: "https://images.unsplash.com/photo-1555706741-8f39aa887cf7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80" },
{ uri: "https://images.unsplash.com/photo-1555706741-fade7dd756a9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80" },
{ uri: "https://images.unsplash.com/photo-1555706742-67a1170e528d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80" }
]
const { width, height } = Dimensions.get("window");
const CARD_HEIGHT = height / 5;
const CARD_WIDTH = CARD_HEIGHT - 50;
export default class screens extends Component {
state = {
markers: [
{
coordinate: {
latitude: 41.414494,
longitude: 2.152695,
},
title: "Parc Güell",
description: "One of the best view in Barcelona. ",
image: Images[0],
},
{
coordinate: {
latitude: 41.403706,
longitude: 2.173504,
},
title: "Sagrada Familia",
description: "This is the second best place in Portland",
image: Images[1],
},
{
coordinate: {
latitude: 41.395382,
longitude: 2.161961,
},
title: "Casa Milà",
description: "This is the third best place in Portland",
image: Images[2],
},
{
coordinate: {
latitude: 41.381905,
longitude: 2.178185,
},
title: "Gothic Quarter",
description: "This is the fourth best place in Portland",
image: Images[3],
},
],
region: {
latitude: 41.390200,
longitude: 2.154007,
latitudeDelta: 0.04864195044303443,
longitudeDelta: 0.040142817690068,
},
};
componentWillMount() {
this.index = 0;
this.animation = new Animated.Value(0);
}
componentDidMount() {
// We should detect when scrolling has stopped then animate
// We should just debounce the event listener here
this.animation.addListener(({ value }) => {
let index = Math.floor(value / CARD_WIDTH + 0.3); // animate 30% away from landing on the next item
if (index >= this.state.markers.length) {
index = this.state.markers.length - 1;
}
if (index <= 0) {
index = 0;
}
clearTimeout(this.regionTimeout);
this.regionTimeout = setTimeout(() => {
if (this.index !== index) {
this.index = index;
const { coordinate } = this.state.markers[index];
this.map.animateToRegion(
{
...coordinate,
latitudeDelta: this.state.region.latitudeDelta,
longitudeDelta: this.state.region.longitudeDelta,
},
350
);
}
}, 10);
});
}
render() {
const interpolations = this.state.markers.map((marker, index) => {
const inputRange = [
(index - 1) * CARD_WIDTH,
index * CARD_WIDTH,
((index + 1) * CARD_WIDTH),
];
const scale = this.animation.interpolate({
inputRange,
outputRange: [1, 2.5, 1],
extrapolate: "clamp",
});
const opacity = this.animation.interpolate({
inputRange,
outputRange: [0.35, 1, 0.35],
extrapolate: "clamp",
});
return { scale, opacity };
});
return (
<View style={styles.container}>
<MapView
ref={map => this.map = map}
initialRegion={this.state.region}
style={styles.container}
>
{this.state.markers.map((marker, index) => {
const scaleStyle = {
transform: [
{
scale: interpolations[index].scale,
},
],
};
const opacityStyle = {
opacity: interpolations[index].opacity,
};
return (
<MapView.Marker key={index} coordinate={marker.coordinate}>
<Animated.View style={[styles.markerWrap, opacityStyle]}>
<Animated.View style={[styles.ring, scaleStyle]} />
<View style={styles.marker} />
</Animated.View>
</MapView.Marker>
);
})}
</MapView>
<Animated.ScrollView
horizontal
scrollEventThrottle={1}
showsHorizontalScrollIndicator={false}
snapToInterval={CARD_WIDTH}
onScroll={Animated.event(
[
{
nativeEvent: {
contentOffset: {
x: this.animation,
},
},
},
],
{ useNativeDriver: true }
)}
style={styles.scrollView}
contentContainerStyle={styles.endPadding}
>
{this.state.markers.map((marker, index) => (
<View style={styles.card} key={index}>
<Image
source={marker.image}
style={styles.cardImage}
resizeMode="cover"
/>
<View style={styles.textContent}>
<Text numberOfLines={1} style={styles.cardtitle}>{marker.title}</Text>
<Text numberOfLines={1} style={styles.cardDescription}>
{marker.description}
</Text>
</View>
</View>
))}
</Animated.ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
scrollView: {
position: "absolute",
bottom: 30,
left: 0,
right: 0,
paddingVertical: 10,
},
endPadding: {
paddingRight: width - CARD_WIDTH,
},
card: {
padding: 10,
elevation: 2,
backgroundColor: "#FFF",
marginHorizontal: 10,
shadowColor: "#000",
shadowRadius: 5,
shadowOpacity: 0.3,
shadowOffset: { x: 2, y: -2 },
height: CARD_HEIGHT,
width: CARD_WIDTH,
overflow: "hidden",
},
cardImage: {
flex: 3,
width: "100%",
height: "100%",
alignSelf: "center",
},
textContent: {
flex: 1,
},
cardtitle: {
fontSize: 12,
marginTop: 5,
fontWeight: "bold",
},
cardDescription: {
fontSize: 12,
color: "#444",
},
markerWrap: {
alignItems: "center",
justifyContent: "center",
},
marker: {
width: 8,
height: 8,
borderRadius: 4,
backgroundColor: "rgba(130,4,150, 0.9)",
},
ring: {
width: 24,
height: 24,
borderRadius: 12,
backgroundColor: "rgba(130,4,150, 0.3)",
position: "absolute",
borderWidth: 1,
borderColor: "rgba(130,4,150, 0.5)",
},
});
create a new file for tab navigation and add the following code:
(I imported your map component as screens)
import React from 'react';
import { Platform } from 'react-native';
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';
import TabBarIcon from '../components/TabBarIcon';
import screens from '../screens/HomeScreen';
import SettingsScreen from '../screens/SettingsScreen';
const HomeStack = createStackNavigator({
Home: screens,
});
HomeStack.navigationOptions = {
tabBarLabel: 'Home',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
Platform.OS === 'ios'
? `ios-information-circle${focused ? '' : '-outline'}`
: 'md-information-circle'
}
/>
),
};
const SettingsStack = createStackNavigator({
Settings: SettingsScreen,
});
SettingsStack.navigationOptions = {
tabBarLabel: 'Settings',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={Platform.OS === 'ios' ? 'ios-options' : 'md-options'}
/>
),
};
export default createBottomTabNavigator({
HomeStack,
SettingsStack,
});
I use ReactNative to develop my iOS APP,to realize the QRCode scanner function,i took the react-native-camera component which provide the barcode scanner function to my project.everything goes all right,but when i had succeed in recognizing a QRCode,next time i use the model,the screen just got frozen,seems like the app goes crashed. something interesting that as the screen is frozen,and once the model cancelled from the left button of navigation,The module can work properly.
I'm not sure whether it's a inner bug of NavigatorIOS,or just the bug of react-native-camera itself.
here is the QRCode component code:
'use strict';
var React = require('react-native');
var Dimensions = require('Dimensions');
var {
StyleSheet,
View,
Text,
TouchableOpacity,
VibrationIOS,
Navigator,
} = React;
var Camera = require('react-native-camera');
var { width, height } = Dimensions.get('window');
var QRCodeScreen = React.createClass({
propTypes: {
cancelButtonVisible: React.PropTypes.bool,
cancelButtonTitle: React.PropTypes.string,
onSucess: React.PropTypes.func,
onCancel: React.PropTypes.func,
},
getDefaultProps: function() {
return {
cancelButtonVisible: false,
cancelButtonTitle: 'Cancel',
barCodeFlag: true,
};
},
_onPressCancel: function() {
var $this = this;
requestAnimationFrame(function() {
$this.props.navigator.pop();
if ($this.props.onCancel) {
$this.props.onCancel();
}
});
},
_onBarCodeRead: function(result) {
var $this = this;
if (this.props.barCodeFlag) {
this.props.barCodeFlag = false;
setTimeout(function() {
VibrationIOS.vibrate();
$this.props.navigator.pop();
$this.props.onSucess(result.data);
}, 1000);
}
},
render: function() {
var cancelButton = null;
if (this.props.cancelButtonVisible) {
cancelButton = <CancelButton onPress={this._onPressCancel} title={this.props.cancelButtonTitle} />;
}
return (
<Camera onBarCodeRead={this._onBarCodeRead} style={styles.camera}>
<View style={styles.rectangleContainer}>
<View style={styles.rectangle}/>
</View>
{cancelButton}
</Camera>
);
},
});
var CancelButton = React.createClass({
render: function() {
return (
<View style={styles.cancelButton}>
<TouchableOpacity onPress={this.props.onPress}>
<Text style={styles.cancelButtonText}>{this.props.title}</Text>
</TouchableOpacity>
</View>
);
},
});
var styles = StyleSheet.create({
camera: {
width:width,
height: height,
alignItems: 'center',
justifyContent: 'center',
},
rectangleContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'transparent',
},
rectangle: {
height: 250,
width: 250,
borderWidth: 2,
borderColor: '#00FF00',
backgroundColor: 'transparent',
},
cancelButton: {
flexDirection: 'row',
justifyContent: 'center',
backgroundColor: 'white',
borderRadius: 3,
padding: 15,
width: 100,
marginBottom: 10,
},
cancelButtonText: {
fontSize: 17,
fontWeight: '500',
color: '#0097CE',
},
});
module.exports = QRCodeScreen;
And In another Component I push this qrCode to the new sence:
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
NavigatorIOS,
AlertIOS,
Navigator,
} = React;
var QRCodeScreen = require('./QRCodeScreen');
var cameraApp = React.createClass({
render: function() {
return (
<NavigatorIOS
style={styles.container}
initialRoute={{
title: 'Index',
backButtonTitle: 'Back',
component: Index,
}}
/>
);
}
});
var Index = React.createClass({
render: function() {
return (
<View style={styles.contentContainer}>
<TouchableOpacity onPress={this._onPressQRCode}>
<Text>Read QRCode</Text>
</TouchableOpacity>
</View>
);
},
_onPressQRCode: function() {
this.props.navigator.push({
component: QRCodeScreen,
title: 'QRCode',
passProps: {
onSucess: this._onSucess,
},
});
},
// onPressCancel:function(){
//
// this.props.navigator.getContext(this).pop();
//
// },
_onSucess: function(result) {
AlertIOS.alert('Code Context', result, [{text: 'Cancel', onPress: ()=>console.log(result)}]);
// console.log(result);
},
});
var styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
contentContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}
});
AppRegistry.registerComponent('Example', () => cameraApp);
Any answer will be helpful!
I think it's a inner bug of NavigatorIOS, or maybe just sth else wrong.
Blew is my code, it is ok.
'use strict';
const React = require('react-native');
const {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
Navigator,
} = React;
var QRCodeScreen = require('./QRCodeScreen');
const CameraApp = () => {
const renderScene = (router, navigator) => {
switch (router.name) {
case 'Index':
return <Index navigator={navigator}/>;
case 'QRCodeScreen':
return <QRCodeScreen
onSucess={router.onSucess}
cancelButtonVisible={router.cancelButtonVisibl}
navigator={navigator}
/>;
}
}
return (
<Navigator
style={styles.container}
initialRoute={{
name: 'Index',
}}
renderScene={renderScene}
/>
);
};
const Index = ({navigator}) => {
const onPressQRCode = () => {
navigator.push({
name: 'QRCodeScreen',
title: 'QRCode',
onSucess: onSucess,
cancelButtonVisible: true,
});
};
const onSucess = (result) => {
console.log(result);
};
return (
<View style={styles.contentContainer}>
<TouchableOpacity onPress={onPressQRCode}>
<Text>Read QRCode</Text>
</TouchableOpacity>
</View>
);
};
module.exports = CameraApp;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
contentContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}
});
you can try Library react native qrcode
https://github.com/moaazsidat/react-native-qrcode-scanner. on me ,
its run. you can try . in ios and android.
I'm trying to use Parse as the data provider for a ListView in a Reactive Native app. I have followed the Parse guide regarding subscribing to a query but for some unknown reason the the data source is empty. I have verified and writing a test object to Parse works fine.
It seems that observe() should be called before getInitialState() or am I missing something?
'use strict';
var React = require('react-native');
var Strings = require('./LocalizedStrings');
var Parse = require('parse').Parse;
var ParseReact = require('parse-react');
Parse.initialize("api_key_here", "api_key_here");
/*
var TestObject = Parse.Object.extend("TestObject");
var testObject = new TestObject();
testObject.save({foo: "bar"}).then(function(object) {
alert("yay! it worked");
});
*/
var {
View,
Text,
ListView,
StyleSheet
} = React;
var styles = StyleSheet.create({
mainContainer: {
flex: 1,
padding: 30,
marginTop: 65,
flexDirection: 'column',
justifyContent: 'center',
backgroundColor: '#fff'
},
title: {
marginBottom: 20,
fontSize: 22,
textAlign: 'center',
color: '#000'
},
});
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}) // assumes immutable objects
var WorkoutList = React.createClass({
mixins: [ParseReact.Mixin],
observe: function() {
return {
workouts: (new Parse.Query("Workout")).descending("createdAt")
};
},
getInitialState: function() {
return {dataSource: ds.cloneWithRows(this.data.workouts)}
},
renderRow: function() {
return (<View><Text>Testing</Text></View>)
},
render: function() {
return (
<View style = {{flex: 1, flexDirection: 'column'}}>
{Strings.workoutsTabTitle}
<ListView
ref = "listview"
dataSource = {this.state.dataSource}
renderRow = {this.renderRow}
automaticallyAdjustContentInsets = {false}
keyboardDismissMode = "onDrag"
keyboardShouldPersistTaps = {true}
showsVerticalScrollIndicator = {true}
style = {styles.mainContainer}
/>
</View>
)
}
})
module.exports = WorkoutList;
I didn't use ParseReact but the Parse Rest API to fetch data from Parse. The following code is called from componentDidMount.
fetch("https://api.parse.com/1/classes/Workout", {
headers: {
"X-Parse-Application-Id": "Your application Id",
"X-Parse-REST-API-Key": "Your API Key"
}
})
.then((response) => response.json())
.then((responseData) => {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.results),
loaded: true,
})
})
.catch(function(error) {
console.log(error)
})
.done();
Using this approach you need to wait until the data is loaded before displaying the ListView. Use this.state.loaded to know when this is the case.
This works too.
observe: function() {
return {
user: ParseReact.currentUser,
abc: (new Parse.Query('abc')).descending('createdAt')
};
},
getInitialState: function () {
return {
dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}),
};
},
render: function() {
return (
<View style={styles.full}>
<ListView
dataSource={this.state.dataSource.cloneWithRows(this.data.abc)}
renderRow={this.renderRow}
/>
</View>
);
},
Hope it helps! Cheers!