mirror of
https://github.com/status-im/react-native.git
synced 2025-01-28 02:04:55 +00:00
Updates from Fri 26, Jun
This commit is contained in:
commit
843e181542
@ -66,6 +66,7 @@ var NavigatorIOSColors = React.createClass({
|
|||||||
tintColor="#FFFFFF"
|
tintColor="#FFFFFF"
|
||||||
barTintColor="#183E63"
|
barTintColor="#183E63"
|
||||||
titleTextColor="#FFFFFF"
|
titleTextColor="#FFFFFF"
|
||||||
|
translucent="true"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -23,6 +23,7 @@ var TypesEnum = {
|
|||||||
easeInEaseOut: true,
|
easeInEaseOut: true,
|
||||||
easeIn: true,
|
easeIn: true,
|
||||||
easeOut: true,
|
easeOut: true,
|
||||||
|
keyboard: true,
|
||||||
};
|
};
|
||||||
var Types = keyMirror(TypesEnum);
|
var Types = keyMirror(TypesEnum);
|
||||||
|
|
||||||
@ -113,4 +114,10 @@ var LayoutAnimation = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for (var key in LayoutAnimation.Presets) {
|
||||||
|
LayoutAnimation[key] = LayoutAnimation.configureNext.bind(
|
||||||
|
null, LayoutAnimation.Presets[key]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = LayoutAnimation;
|
module.exports = LayoutAnimation;
|
||||||
|
@ -35,6 +35,34 @@ type MapRegion = {
|
|||||||
var MapView = React.createClass({
|
var MapView = React.createClass({
|
||||||
mixins: [NativeMethodsMixin],
|
mixins: [NativeMethodsMixin],
|
||||||
|
|
||||||
|
checkAnnotationIds: function (annotations: Array<Object>) {
|
||||||
|
|
||||||
|
var newAnnotations = annotations.map(function (annotation) {
|
||||||
|
if (!annotation.id) {
|
||||||
|
// TODO: add a base64 (or similar) encoder here
|
||||||
|
annotation.id = encodeURIComponent(JSON.stringify(annotation));
|
||||||
|
}
|
||||||
|
|
||||||
|
return annotation;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
annotations: newAnnotations
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillMount: function() {
|
||||||
|
if (this.props.annotations) {
|
||||||
|
this.checkAnnotationIds(this.props.annotations);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillReceiveProps: function(nextProps: Object) {
|
||||||
|
if (nextProps.annotations) {
|
||||||
|
this.checkAnnotationIds(nextProps.annotations);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
/**
|
/**
|
||||||
* Used to style and layout the `MapView`. See `StyleSheet.js` and
|
* Used to style and layout the `MapView`. See `StyleSheet.js` and
|
||||||
@ -84,14 +112,14 @@ var MapView = React.createClass({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The map type to be displayed.
|
* The map type to be displayed.
|
||||||
*
|
*
|
||||||
* - standard: standard road map (default)
|
* - standard: standard road map (default)
|
||||||
* - satellite: satellite view
|
* - satellite: satellite view
|
||||||
* - hybrid: satellite view with roads and points of interest overlayed
|
* - hybrid: satellite view with roads and points of interest overlayed
|
||||||
*/
|
*/
|
||||||
mapType: React.PropTypes.oneOf([
|
mapType: React.PropTypes.oneOf([
|
||||||
'standard',
|
'standard',
|
||||||
'satellite',
|
'satellite',
|
||||||
'hybrid',
|
'hybrid',
|
||||||
]),
|
]),
|
||||||
|
|
||||||
@ -126,11 +154,34 @@ var MapView = React.createClass({
|
|||||||
latitude: React.PropTypes.number.isRequired,
|
latitude: React.PropTypes.number.isRequired,
|
||||||
longitude: React.PropTypes.number.isRequired,
|
longitude: React.PropTypes.number.isRequired,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the pin drop should be animated or not
|
||||||
|
*/
|
||||||
|
animateDrop: React.PropTypes.bool,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotation title/subtile.
|
* Annotation title/subtile.
|
||||||
*/
|
*/
|
||||||
title: React.PropTypes.string,
|
title: React.PropTypes.string,
|
||||||
subtitle: React.PropTypes.string,
|
subtitle: React.PropTypes.string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the Annotation has callout buttons.
|
||||||
|
*/
|
||||||
|
hasLeftCallout: React.PropTypes.bool,
|
||||||
|
hasRightCallout: React.PropTypes.bool,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handlers for callout buttons.
|
||||||
|
*/
|
||||||
|
onLeftCalloutPress: React.PropTypes.func,
|
||||||
|
onRightCalloutPress: React.PropTypes.func,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* annotation id
|
||||||
|
*/
|
||||||
|
id: React.PropTypes.string
|
||||||
|
|
||||||
})),
|
})),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -158,6 +209,11 @@ var MapView = React.createClass({
|
|||||||
* Callback that is called once, when the user is done moving the map.
|
* Callback that is called once, when the user is done moving the map.
|
||||||
*/
|
*/
|
||||||
onRegionChangeComplete: React.PropTypes.func,
|
onRegionChangeComplete: React.PropTypes.func,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that is called once, when the user is clicked on a annotation.
|
||||||
|
*/
|
||||||
|
onAnnotationPress: React.PropTypes.func,
|
||||||
},
|
},
|
||||||
|
|
||||||
_onChange: function(event: Event) {
|
_onChange: function(event: Event) {
|
||||||
@ -170,8 +226,34 @@ var MapView = React.createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onPress: function(event: Event) {
|
||||||
|
if (event.nativeEvent.action === 'annotation-click') {
|
||||||
|
this.props.onAnnotationPress && this.props.onAnnotationPress(event.nativeEvent.annotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.nativeEvent.action === 'callout-click') {
|
||||||
|
if (!this.props.annotations) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the annotation with the id of what has been pressed
|
||||||
|
for (var i = 0; i < this.props.annotations.length; i++) {
|
||||||
|
var annotation = this.props.annotations[i];
|
||||||
|
if (annotation.id === event.nativeEvent.annotationId) {
|
||||||
|
// Pass the right function
|
||||||
|
if (event.nativeEvent.side === 'left') {
|
||||||
|
annotation.onLeftCalloutPress && annotation.onLeftCalloutPress(event.nativeEvent);
|
||||||
|
} else if (event.nativeEvent.side === 'right') {
|
||||||
|
annotation.onRightCalloutPress && annotation.onRightCalloutPress(event.nativeEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return <RCTMap {...this.props} onChange={this._onChange} />;
|
return <RCTMap {...this.props} onPress={this._onPress} onChange={this._onChange} />;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -179,6 +261,7 @@ if (Platform.OS === 'android') {
|
|||||||
var RCTMap = createReactNativeComponentClass({
|
var RCTMap = createReactNativeComponentClass({
|
||||||
validAttributes: merge(
|
validAttributes: merge(
|
||||||
ReactNativeViewAttributes.UIView, {
|
ReactNativeViewAttributes.UIView, {
|
||||||
|
active: true,
|
||||||
showsUserLocation: true,
|
showsUserLocation: true,
|
||||||
zoomEnabled: true,
|
zoomEnabled: true,
|
||||||
rotateEnabled: true,
|
rotateEnabled: true,
|
||||||
|
@ -57,6 +57,7 @@ var RCTNavigatorItem = createReactNativeComponentClass({
|
|||||||
backButtonIcon: true,
|
backButtonIcon: true,
|
||||||
backButtonTitle: true,
|
backButtonTitle: true,
|
||||||
tintColor: true,
|
tintColor: true,
|
||||||
|
translucent: true,
|
||||||
navigationBarHidden: true,
|
navigationBarHidden: true,
|
||||||
titleTextColor: true,
|
titleTextColor: true,
|
||||||
style: true,
|
style: true,
|
||||||
@ -300,6 +301,11 @@ var NavigatorIOS = React.createClass({
|
|||||||
*/
|
*/
|
||||||
titleTextColor: PropTypes.string,
|
titleTextColor: PropTypes.string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Boolean value that indicates whether the navigation bar is translucent
|
||||||
|
*/
|
||||||
|
translucent: PropTypes.bool,
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
navigator: (undefined: ?Object),
|
navigator: (undefined: ?Object),
|
||||||
@ -609,6 +615,7 @@ var NavigatorIOS = React.createClass({
|
|||||||
navigationBarHidden={this.props.navigationBarHidden}
|
navigationBarHidden={this.props.navigationBarHidden}
|
||||||
tintColor={this.props.tintColor}
|
tintColor={this.props.tintColor}
|
||||||
barTintColor={this.props.barTintColor}
|
barTintColor={this.props.barTintColor}
|
||||||
|
translucent={this.props.translucent}
|
||||||
titleTextColor={this.props.titleTextColor}>
|
titleTextColor={this.props.titleTextColor}>
|
||||||
<Component
|
<Component
|
||||||
navigator={this.navigator}
|
navigator={this.navigator}
|
||||||
|
@ -276,7 +276,9 @@ var ListView = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
componentDidUpdate: function() {
|
componentDidUpdate: function() {
|
||||||
this._measureAndUpdateScrollProps();
|
this.requestAnimationFrame(() => {
|
||||||
|
this._measureAndUpdateScrollProps();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onRowHighlighted: function(sectionID, rowID) {
|
onRowHighlighted: function(sectionID, rowID) {
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
var AnimationsDebugModule = require('NativeModules').AnimationsDebugModule;
|
var AnimationsDebugModule = require('NativeModules').AnimationsDebugModule;
|
||||||
var Dimensions = require('Dimensions');
|
var Dimensions = require('Dimensions');
|
||||||
var InteractionMixin = require('InteractionMixin');
|
var InteractionMixin = require('InteractionMixin');
|
||||||
|
var Map = require('Map');
|
||||||
var NavigationContext = require('NavigationContext');
|
var NavigationContext = require('NavigationContext');
|
||||||
var NavigatorBreadcrumbNavigationBar = require('NavigatorBreadcrumbNavigationBar');
|
var NavigatorBreadcrumbNavigationBar = require('NavigatorBreadcrumbNavigationBar');
|
||||||
var NavigatorNavigationBar = require('NavigatorNavigationBar');
|
var NavigatorNavigationBar = require('NavigatorNavigationBar');
|
||||||
@ -257,6 +258,8 @@ var Navigator = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
|
this._renderedSceneMap = new Map();
|
||||||
|
|
||||||
var routeStack = this.props.initialRouteStack || [this.props.initialRoute];
|
var routeStack = this.props.initialRouteStack || [this.props.initialRoute];
|
||||||
invariant(
|
invariant(
|
||||||
routeStack.length >= 1,
|
routeStack.length >= 1,
|
||||||
@ -276,10 +279,6 @@ var Navigator = React.createClass({
|
|||||||
),
|
),
|
||||||
idStack: routeStack.map(() => getuid()),
|
idStack: routeStack.map(() => getuid()),
|
||||||
routeStack,
|
routeStack,
|
||||||
// `updatingRange*` allows us to only render the visible or staged scenes
|
|
||||||
// On first render, we will render every scene in the initialRouteStack
|
|
||||||
updatingRangeStart: 0,
|
|
||||||
updatingRangeLength: routeStack.length,
|
|
||||||
presentedIndex: initialRouteIndex,
|
presentedIndex: initialRouteIndex,
|
||||||
transitionFromIndex: null,
|
transitionFromIndex: null,
|
||||||
activeGesture: null,
|
activeGesture: null,
|
||||||
@ -351,8 +350,6 @@ var Navigator = React.createClass({
|
|||||||
sceneConfigStack: nextRouteStack.map(
|
sceneConfigStack: nextRouteStack.map(
|
||||||
this.props.configureScene
|
this.props.configureScene
|
||||||
),
|
),
|
||||||
updatingRangeStart: 0,
|
|
||||||
updatingRangeLength: nextRouteStack.length,
|
|
||||||
presentedIndex: destIndex,
|
presentedIndex: destIndex,
|
||||||
activeGesture: null,
|
activeGesture: null,
|
||||||
transitionFromIndex: null,
|
transitionFromIndex: null,
|
||||||
@ -395,7 +392,6 @@ var Navigator = React.createClass({
|
|||||||
this.spring.getSpringConfig().tension = sceneConfig.springTension;
|
this.spring.getSpringConfig().tension = sceneConfig.springTension;
|
||||||
this.spring.setVelocity(velocity || sceneConfig.defaultTransitionVelocity);
|
this.spring.setVelocity(velocity || sceneConfig.defaultTransitionVelocity);
|
||||||
this.spring.setEndValue(1);
|
this.spring.setEndValue(1);
|
||||||
this._emitWillFocus(this.state.routeStack[this.state.presentedIndex]);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -461,6 +457,7 @@ var Navigator = React.createClass({
|
|||||||
if (this.state.transitionQueue.length) {
|
if (this.state.transitionQueue.length) {
|
||||||
var queuedTransition = this.state.transitionQueue.shift();
|
var queuedTransition = this.state.transitionQueue.shift();
|
||||||
this._enableScene(queuedTransition.destIndex);
|
this._enableScene(queuedTransition.destIndex);
|
||||||
|
this._emitWillFocus(this.state.routeStack[queuedTransition.destIndex]);
|
||||||
this._transitionTo(
|
this._transitionTo(
|
||||||
queuedTransition.destIndex,
|
queuedTransition.destIndex,
|
||||||
queuedTransition.velocity,
|
queuedTransition.velocity,
|
||||||
@ -660,6 +657,7 @@ var Navigator = React.createClass({
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// The gesture has enough velocity to complete, so we transition to the gesture's destination
|
// The gesture has enough velocity to complete, so we transition to the gesture's destination
|
||||||
|
this._emitWillFocus(this.state.routeStack[destIndex]);
|
||||||
this._transitionTo(
|
this._transitionTo(
|
||||||
destIndex,
|
destIndex,
|
||||||
transitionVelocity,
|
transitionVelocity,
|
||||||
@ -829,11 +827,6 @@ var Navigator = React.createClass({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_resetUpdatingRange: function() {
|
|
||||||
this.state.updatingRangeStart = 0;
|
|
||||||
this.state.updatingRangeLength = this.state.routeStack.length;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getDestIndexWithinBounds: function(n) {
|
_getDestIndexWithinBounds: function(n) {
|
||||||
var currentIndex = this.state.presentedIndex;
|
var currentIndex = this.state.presentedIndex;
|
||||||
var destIndex = currentIndex + n;
|
var destIndex = currentIndex + n;
|
||||||
@ -851,15 +844,9 @@ var Navigator = React.createClass({
|
|||||||
|
|
||||||
_jumpN: function(n) {
|
_jumpN: function(n) {
|
||||||
var destIndex = this._getDestIndexWithinBounds(n);
|
var destIndex = this._getDestIndexWithinBounds(n);
|
||||||
var requestTransitionAndResetUpdatingRange = () => {
|
this._enableScene(destIndex);
|
||||||
this._enableScene(destIndex);
|
this._emitWillFocus(this.state.routeStack[destIndex]);
|
||||||
this._transitionTo(destIndex);
|
this._transitionTo(destIndex);
|
||||||
this._resetUpdatingRange();
|
|
||||||
};
|
|
||||||
this.setState({
|
|
||||||
updatingRangeStart: destIndex,
|
|
||||||
updatingRangeLength: 1,
|
|
||||||
}, requestTransitionAndResetUpdatingRange);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
jumpTo: function(route) {
|
jumpTo: function(route) {
|
||||||
@ -891,18 +878,15 @@ var Navigator = React.createClass({
|
|||||||
var nextAnimationConfigStack = activeAnimationConfigStack.concat([
|
var nextAnimationConfigStack = activeAnimationConfigStack.concat([
|
||||||
this.props.configureScene(route),
|
this.props.configureScene(route),
|
||||||
]);
|
]);
|
||||||
var requestTransitionAndResetUpdatingRange = () => {
|
this._emitWillFocus(nextStack[destIndex]);
|
||||||
this._enableScene(destIndex);
|
|
||||||
this._transitionTo(destIndex);
|
|
||||||
this._resetUpdatingRange();
|
|
||||||
};
|
|
||||||
this.setState({
|
this.setState({
|
||||||
idStack: nextIDStack,
|
idStack: nextIDStack,
|
||||||
routeStack: nextStack,
|
routeStack: nextStack,
|
||||||
sceneConfigStack: nextAnimationConfigStack,
|
sceneConfigStack: nextAnimationConfigStack,
|
||||||
updatingRangeStart: nextStack.length - 1,
|
}, () => {
|
||||||
updatingRangeLength: 1,
|
this._enableScene(destIndex);
|
||||||
}, requestTransitionAndResetUpdatingRange);
|
this._transitionTo(destIndex);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_popN: function(n) {
|
_popN: function(n) {
|
||||||
@ -915,6 +899,7 @@ var Navigator = React.createClass({
|
|||||||
);
|
);
|
||||||
var popIndex = this.state.presentedIndex - n;
|
var popIndex = this.state.presentedIndex - n;
|
||||||
this._enableScene(popIndex);
|
this._enableScene(popIndex);
|
||||||
|
this._emitWillFocus(this.state.routeStack[popIndex]);
|
||||||
this._transitionTo(
|
this._transitionTo(
|
||||||
popIndex,
|
popIndex,
|
||||||
null, // default velocity
|
null, // default velocity
|
||||||
@ -954,16 +939,15 @@ var Navigator = React.createClass({
|
|||||||
nextRouteStack[index] = route;
|
nextRouteStack[index] = route;
|
||||||
nextAnimationModeStack[index] = this.props.configureScene(route);
|
nextAnimationModeStack[index] = this.props.configureScene(route);
|
||||||
|
|
||||||
|
if (index === this.state.presentedIndex) {
|
||||||
|
this._emitWillFocus(route);
|
||||||
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
idStack: nextIDStack,
|
idStack: nextIDStack,
|
||||||
routeStack: nextRouteStack,
|
routeStack: nextRouteStack,
|
||||||
sceneConfigStack: nextAnimationModeStack,
|
sceneConfigStack: nextAnimationModeStack,
|
||||||
updatingRangeStart: index,
|
|
||||||
updatingRangeLength: 1,
|
|
||||||
}, () => {
|
}, () => {
|
||||||
this._resetUpdatingRange();
|
|
||||||
if (index === this.state.presentedIndex) {
|
if (index === this.state.presentedIndex) {
|
||||||
this._emitWillFocus(route);
|
|
||||||
this._emitDidFocus(route);
|
this._emitDidFocus(route);
|
||||||
}
|
}
|
||||||
cb && cb();
|
cb && cb();
|
||||||
@ -1034,69 +1018,17 @@ var Navigator = React.createClass({
|
|||||||
var newStackLength = index + 1;
|
var newStackLength = index + 1;
|
||||||
// Remove any unneeded rendered routes.
|
// Remove any unneeded rendered routes.
|
||||||
if (newStackLength < this.state.routeStack.length) {
|
if (newStackLength < this.state.routeStack.length) {
|
||||||
var updatingRangeStart = newStackLength; // One past the top
|
|
||||||
var updatingRangeLength = this.state.routeStack.length - newStackLength + 1;
|
|
||||||
this.state.idStack.slice(newStackLength).map((removingId) => {
|
this.state.idStack.slice(newStackLength).map((removingId) => {
|
||||||
this._itemRefs[removingId] = null;
|
this._itemRefs[removingId] = null;
|
||||||
});
|
});
|
||||||
this.setState({
|
this.setState({
|
||||||
updatingRangeStart: updatingRangeStart,
|
|
||||||
updatingRangeLength: updatingRangeLength,
|
|
||||||
sceneConfigStack: this.state.sceneConfigStack.slice(0, newStackLength),
|
sceneConfigStack: this.state.sceneConfigStack.slice(0, newStackLength),
|
||||||
idStack: this.state.idStack.slice(0, newStackLength),
|
idStack: this.state.idStack.slice(0, newStackLength),
|
||||||
routeStack: this.state.routeStack.slice(0, newStackLength),
|
routeStack: this.state.routeStack.slice(0, newStackLength),
|
||||||
}, this._resetUpdatingRange);
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_renderOptimizedScenes: function() {
|
|
||||||
// To avoid rendering scenes that are not visible, we use
|
|
||||||
// updatingRangeStart and updatingRangeLength to track the scenes that need
|
|
||||||
// to be updated.
|
|
||||||
|
|
||||||
// To avoid visual glitches, we never re-render scenes during a transition.
|
|
||||||
// We assume that `state.updatingRangeLength` will have a length during the
|
|
||||||
// initial render of any scene
|
|
||||||
var shouldRenderScenes = this.state.updatingRangeLength !== 0;
|
|
||||||
if (shouldRenderScenes) {
|
|
||||||
return (
|
|
||||||
<StaticContainer shouldUpdate={true}>
|
|
||||||
<View
|
|
||||||
style={styles.transitioner}
|
|
||||||
{...this.panGesture.panHandlers}
|
|
||||||
onTouchStart={this._handleTouchStart}
|
|
||||||
onResponderTerminationRequest={
|
|
||||||
this._handleResponderTerminationRequest
|
|
||||||
}>
|
|
||||||
{this.state.routeStack.map(this._renderOptimizedScene)}
|
|
||||||
</View>
|
|
||||||
</StaticContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// If no scenes are changing, we can save render time. React will notice
|
|
||||||
// that we are rendering a StaticContainer in the same place, so the
|
|
||||||
// existing element will be updated. When React asks the element
|
|
||||||
// shouldComponentUpdate, the StaticContainer will return false, and the
|
|
||||||
// children from the previous reconciliation will remain.
|
|
||||||
return (
|
|
||||||
<StaticContainer shouldUpdate={false} />
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
_renderOptimizedScene: function(route, i) {
|
|
||||||
var shouldRenderScene =
|
|
||||||
i >= this.state.updatingRangeStart &&
|
|
||||||
i <= this.state.updatingRangeStart + this.state.updatingRangeLength;
|
|
||||||
var scene = shouldRenderScene ? this._renderScene(route, i) : null;
|
|
||||||
return (
|
|
||||||
<StaticContainer
|
|
||||||
key={'nav' + i}
|
|
||||||
shouldUpdate={shouldRenderScene}>
|
|
||||||
{scene}
|
|
||||||
</StaticContainer>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
_renderScene: function(route, i) {
|
_renderScene: function(route, i) {
|
||||||
var child = this.props.renderScene(
|
var child = this.props.renderScene(
|
||||||
route,
|
route,
|
||||||
@ -1146,9 +1078,30 @@ var Navigator = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
var newRenderedSceneMap = new Map();
|
||||||
|
var scenes = this.state.routeStack.map((route, index) => {
|
||||||
|
var renderedScene;
|
||||||
|
if (this._renderedSceneMap.has(route) &&
|
||||||
|
index !== this.state.presentedIndex) {
|
||||||
|
renderedScene = this._renderedSceneMap.get(route);
|
||||||
|
} else {
|
||||||
|
renderedScene = this._renderScene(route, index);
|
||||||
|
}
|
||||||
|
newRenderedSceneMap.set(route, renderedScene);
|
||||||
|
return renderedScene;
|
||||||
|
});
|
||||||
|
this._renderedSceneMap = newRenderedSceneMap;
|
||||||
return (
|
return (
|
||||||
<View style={[styles.container, this.props.style]}>
|
<View style={[styles.container, this.props.style]}>
|
||||||
{this._renderOptimizedScenes()}
|
<View
|
||||||
|
style={styles.transitioner}
|
||||||
|
{...this.panGesture.panHandlers}
|
||||||
|
onTouchStart={this._handleTouchStart}
|
||||||
|
onResponderTerminationRequest={
|
||||||
|
this._handleResponderTerminationRequest
|
||||||
|
}>
|
||||||
|
{scenes}
|
||||||
|
</View>
|
||||||
{this._renderNavigationBar()}
|
{this._renderNavigationBar()}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
@ -76,15 +76,17 @@ class MessageQueue {
|
|||||||
* Public APIs
|
* Public APIs
|
||||||
*/
|
*/
|
||||||
processBatch(batch) {
|
processBatch(batch) {
|
||||||
ReactUpdates.batchedUpdates(() => {
|
guard(() => {
|
||||||
batch.forEach((call) => {
|
ReactUpdates.batchedUpdates(() => {
|
||||||
let method = call.method === 'callFunctionReturnFlushedQueue' ?
|
batch.forEach((call) => {
|
||||||
'__callFunction' : '__invokeCallback';
|
let method = call.method === 'callFunctionReturnFlushedQueue' ?
|
||||||
guard(() => this[method].apply(this, call.args));
|
'__callFunction' : '__invokeCallback';
|
||||||
|
guard(() => this[method].apply(this, call.args));
|
||||||
|
});
|
||||||
|
BridgeProfiling.profile('ReactUpdates.batchedUpdates()');
|
||||||
});
|
});
|
||||||
BridgeProfiling.profile('ReactUpdates.batchedUpdates()');
|
BridgeProfiling.profileEnd();
|
||||||
});
|
});
|
||||||
BridgeProfiling.profileEnd();
|
|
||||||
return this.flushedQueue();
|
return this.flushedQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -997,6 +997,7 @@ RCT_ENUM_CONVERTER(RCTAnimationType, (@{
|
|||||||
@"easeIn": @(RCTAnimationTypeEaseIn),
|
@"easeIn": @(RCTAnimationTypeEaseIn),
|
||||||
@"easeOut": @(RCTAnimationTypeEaseOut),
|
@"easeOut": @(RCTAnimationTypeEaseOut),
|
||||||
@"easeInEaseOut": @(RCTAnimationTypeEaseInEaseOut),
|
@"easeInEaseOut": @(RCTAnimationTypeEaseInEaseOut),
|
||||||
|
@"keyboard": @(RCTAnimationTypeKeyboard),
|
||||||
}), RCTAnimationTypeEaseInEaseOut, integerValue)
|
}), RCTAnimationTypeEaseInEaseOut, integerValue)
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
19
React/Modules/RCTPointAnnotation.h
Normal file
19
React/Modules/RCTPointAnnotation.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <MapKit/MapKit.h>
|
||||||
|
|
||||||
|
@interface RCTPointAnnotation : MKPointAnnotation <MKAnnotation>
|
||||||
|
|
||||||
|
@property (nonatomic, copy) NSString *identifier;
|
||||||
|
@property (nonatomic, assign) BOOL hasLeftCallout;
|
||||||
|
@property (nonatomic, assign) BOOL hasRightCallout;
|
||||||
|
@property (nonatomic, assign) BOOL animateDrop;
|
||||||
|
|
||||||
|
@end
|
14
React/Modules/RCTPointAnnotation.m
Normal file
14
React/Modules/RCTPointAnnotation.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "RCTPointAnnotation.h"
|
||||||
|
|
||||||
|
@implementation RCTPointAnnotation
|
||||||
|
|
||||||
|
@end
|
@ -58,20 +58,23 @@ static void RCTTraverseViewNodes(id<RCTViewNodeProtocol> view, react_view_node_b
|
|||||||
|
|
||||||
@implementation RCTAnimation
|
@implementation RCTAnimation
|
||||||
|
|
||||||
static UIViewAnimationCurve UIViewAnimationCurveFromRCTAnimationType(RCTAnimationType type)
|
static UIViewAnimationOptions UIViewAnimationOptionsFromRCTAnimationType(RCTAnimationType type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case RCTAnimationTypeLinear:
|
case RCTAnimationTypeLinear:
|
||||||
return UIViewAnimationCurveLinear;
|
return UIViewAnimationOptionCurveLinear;
|
||||||
case RCTAnimationTypeEaseIn:
|
case RCTAnimationTypeEaseIn:
|
||||||
return UIViewAnimationCurveEaseIn;
|
return UIViewAnimationOptionCurveEaseIn;
|
||||||
case RCTAnimationTypeEaseOut:
|
case RCTAnimationTypeEaseOut:
|
||||||
return UIViewAnimationCurveEaseOut;
|
return UIViewAnimationOptionCurveEaseOut;
|
||||||
case RCTAnimationTypeEaseInEaseOut:
|
case RCTAnimationTypeEaseInEaseOut:
|
||||||
return UIViewAnimationCurveEaseInOut;
|
return UIViewAnimationOptionCurveEaseInOut;
|
||||||
|
case RCTAnimationTypeKeyboard:
|
||||||
|
// http://stackoverflow.com/questions/18870447/how-to-use-the-default-ios7-uianimation-curve
|
||||||
|
return (UIViewAnimationOptions)(7 << 16);
|
||||||
default:
|
default:
|
||||||
RCTLogError(@"Unsupported animation type %zd", type);
|
RCTLogError(@"Unsupported animation type %zd", type);
|
||||||
return UIViewAnimationCurveEaseInOut;
|
return UIViewAnimationOptionCurveEaseInOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +126,7 @@ static UIViewAnimationCurve UIViewAnimationCurveFromRCTAnimationType(RCTAnimatio
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState |
|
UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState |
|
||||||
UIViewAnimationCurveFromRCTAnimationType(_animationType);
|
UIViewAnimationOptionsFromRCTAnimationType(_animationType);
|
||||||
|
|
||||||
[UIView animateWithDuration:_duration
|
[UIView animateWithDuration:_duration
|
||||||
delay:_delay
|
delay:_delay
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
58114A171AAE854800E7D092 /* RCTPickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A151AAE854800E7D092 /* RCTPickerManager.m */; };
|
58114A171AAE854800E7D092 /* RCTPickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A151AAE854800E7D092 /* RCTPickerManager.m */; };
|
||||||
58114A501AAE93D500E7D092 /* RCTAsyncLocalStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A4E1AAE93D500E7D092 /* RCTAsyncLocalStorage.m */; };
|
58114A501AAE93D500E7D092 /* RCTAsyncLocalStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A4E1AAE93D500E7D092 /* RCTAsyncLocalStorage.m */; };
|
||||||
58C571C11AA56C1900CDF9C8 /* RCTDatePickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */; };
|
58C571C11AA56C1900CDF9C8 /* RCTDatePickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */; };
|
||||||
|
63F014C01B02080B003B75D2 /* RCTPointAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F014BF1B02080B003B75D2 /* RCTPointAnnotation.m */; };
|
||||||
830A229E1A66C68A008503DA /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; };
|
830A229E1A66C68A008503DA /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; };
|
||||||
830BA4551A8E3BDA00D53203 /* RCTCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 830BA4541A8E3BDA00D53203 /* RCTCache.m */; };
|
830BA4551A8E3BDA00D53203 /* RCTCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 830BA4541A8E3BDA00D53203 /* RCTCache.m */; };
|
||||||
832348161A77A5AA00B55238 /* Layout.c in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FC71A68125100A75B9A /* Layout.c */; };
|
832348161A77A5AA00B55238 /* Layout.c in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FC71A68125100A75B9A /* Layout.c */; };
|
||||||
@ -213,6 +214,8 @@
|
|||||||
58114A4F1AAE93D500E7D092 /* RCTAsyncLocalStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAsyncLocalStorage.h; sourceTree = "<group>"; };
|
58114A4F1AAE93D500E7D092 /* RCTAsyncLocalStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAsyncLocalStorage.h; sourceTree = "<group>"; };
|
||||||
58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDatePickerManager.m; sourceTree = "<group>"; };
|
58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDatePickerManager.m; sourceTree = "<group>"; };
|
||||||
58C571C01AA56C1900CDF9C8 /* RCTDatePickerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDatePickerManager.h; sourceTree = "<group>"; };
|
58C571C01AA56C1900CDF9C8 /* RCTDatePickerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDatePickerManager.h; sourceTree = "<group>"; };
|
||||||
|
63F014BE1B02080B003B75D2 /* RCTPointAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPointAnnotation.h; sourceTree = "<group>"; };
|
||||||
|
63F014BF1B02080B003B75D2 /* RCTPointAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTPointAnnotation.m; sourceTree = "<group>"; };
|
||||||
830213F31A654E0800B993E6 /* RCTBridgeModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTBridgeModule.h; sourceTree = "<group>"; };
|
830213F31A654E0800B993E6 /* RCTBridgeModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTBridgeModule.h; sourceTree = "<group>"; };
|
||||||
830A229C1A66C68A008503DA /* RCTRootView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootView.h; sourceTree = "<group>"; };
|
830A229C1A66C68A008503DA /* RCTRootView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootView.h; sourceTree = "<group>"; };
|
||||||
830A229D1A66C68A008503DA /* RCTRootView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootView.m; sourceTree = "<group>"; };
|
830A229D1A66C68A008503DA /* RCTRootView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootView.m; sourceTree = "<group>"; };
|
||||||
@ -291,6 +294,8 @@
|
|||||||
13B07FEE1A69327A00A75B9A /* RCTTiming.m */,
|
13B07FEE1A69327A00A75B9A /* RCTTiming.m */,
|
||||||
13E067481A70F434002CDEE1 /* RCTUIManager.h */,
|
13E067481A70F434002CDEE1 /* RCTUIManager.h */,
|
||||||
13E067491A70F434002CDEE1 /* RCTUIManager.m */,
|
13E067491A70F434002CDEE1 /* RCTUIManager.m */,
|
||||||
|
63F014BE1B02080B003B75D2 /* RCTPointAnnotation.h */,
|
||||||
|
63F014BF1B02080B003B75D2 /* RCTPointAnnotation.m */,
|
||||||
);
|
);
|
||||||
path = Modules;
|
path = Modules;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -599,6 +604,7 @@
|
|||||||
830BA4551A8E3BDA00D53203 /* RCTCache.m in Sources */,
|
830BA4551A8E3BDA00D53203 /* RCTCache.m in Sources */,
|
||||||
137327E71AA5CF210034F82E /* RCTTabBar.m in Sources */,
|
137327E71AA5CF210034F82E /* RCTTabBar.m in Sources */,
|
||||||
00C1A2B31AC0B7E000E89A1C /* RCTDevMenu.m in Sources */,
|
00C1A2B31AC0B7E000E89A1C /* RCTDevMenu.m in Sources */,
|
||||||
|
63F014C01B02080B003B75D2 /* RCTPointAnnotation.m in Sources */,
|
||||||
14435CE51AAC4AE100FC20F4 /* RCTMap.m in Sources */,
|
14435CE51AAC4AE100FC20F4 /* RCTMap.m in Sources */,
|
||||||
134FCB3E1A6E7F0800051CC8 /* RCTWebViewExecutor.m in Sources */,
|
134FCB3E1A6E7F0800051CC8 /* RCTWebViewExecutor.m in Sources */,
|
||||||
13B0801C1A69489C00A75B9A /* RCTNavItem.m in Sources */,
|
13B0801C1A69489C00A75B9A /* RCTNavItem.m in Sources */,
|
||||||
|
@ -15,4 +15,5 @@ typedef NS_ENUM(NSInteger, RCTAnimationType) {
|
|||||||
RCTAnimationTypeEaseIn,
|
RCTAnimationTypeEaseIn,
|
||||||
RCTAnimationTypeEaseOut,
|
RCTAnimationTypeEaseOut,
|
||||||
RCTAnimationTypeEaseInEaseOut,
|
RCTAnimationTypeEaseInEaseOut,
|
||||||
|
RCTAnimationTypeKeyboard,
|
||||||
};
|
};
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
//
|
/**
|
||||||
// RCTConvert+CoreLocation.h
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
// React
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Created by Nick Lockwood on 12/04/2015.
|
* This source code is licensed under the BSD-style license found in the
|
||||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
//
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import <CoreLocation/CoreLocation.h>
|
#import <CoreLocation/CoreLocation.h>
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
//
|
/**
|
||||||
// RCTConvert+CoreLocation.m
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
// React
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Created by Nick Lockwood on 12/04/2015.
|
* This source code is licensed under the BSD-style license found in the
|
||||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
//
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import "RCTConvert+CoreLocation.h"
|
#import "RCTConvert+CoreLocation.h"
|
||||||
|
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
//
|
/**
|
||||||
// RCTConvert+MapKit.h
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
// React
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Created by Nick Lockwood on 12/04/2015.
|
* This source code is licensed under the BSD-style license found in the
|
||||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
//
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import <MapKit/MapKit.h>
|
#import <MapKit/MapKit.h>
|
||||||
|
|
||||||
|
#import "RCTPointAnnotation.h"
|
||||||
#import "RCTConvert.h"
|
#import "RCTConvert.h"
|
||||||
|
|
||||||
@interface RCTConvert (MapKit)
|
@interface RCTConvert (MapKit)
|
||||||
@ -16,8 +18,12 @@
|
|||||||
+ (MKCoordinateRegion)MKCoordinateRegion:(id)json;
|
+ (MKCoordinateRegion)MKCoordinateRegion:(id)json;
|
||||||
+ (MKShape *)MKShape:(id)json;
|
+ (MKShape *)MKShape:(id)json;
|
||||||
+ (MKMapType)MKMapType:(id)json;
|
+ (MKMapType)MKMapType:(id)json;
|
||||||
|
+ (RCTPointAnnotation *)RCTPointAnnotation:(id)json;
|
||||||
|
|
||||||
typedef NSArray MKShapeArray;
|
typedef NSArray MKShapeArray;
|
||||||
+ (MKShapeArray *)MKShapeArray:(id)json;
|
+ (MKShapeArray *)MKShapeArray:(id)json;
|
||||||
|
|
||||||
|
typedef NSArray RCTPointAnnotationArray;
|
||||||
|
+ (RCTPointAnnotationArray *)RCTPointAnnotationArray:(id)json;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
//
|
/**
|
||||||
// RCTConvert+MapKit.m
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
// React
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Created by Nick Lockwood on 12/04/2015.
|
* This source code is licensed under the BSD-style license found in the
|
||||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
//
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import "RCTConvert+MapKit.h"
|
#import "RCTConvert+MapKit.h"
|
||||||
|
|
||||||
#import "RCTConvert+CoreLocation.h"
|
#import "RCTConvert+CoreLocation.h"
|
||||||
|
#import "RCTPointAnnotation.h"
|
||||||
|
|
||||||
@implementation RCTConvert(MapKit)
|
@implementation RCTConvert(MapKit)
|
||||||
|
|
||||||
@ -49,4 +50,20 @@ RCT_ENUM_CONVERTER(MKMapType, (@{
|
|||||||
@"hybrid": @(MKMapTypeHybrid),
|
@"hybrid": @(MKMapTypeHybrid),
|
||||||
}), MKMapTypeStandard, integerValue)
|
}), MKMapTypeStandard, integerValue)
|
||||||
|
|
||||||
|
+ (RCTPointAnnotation *)RCTPointAnnotation:(id)json
|
||||||
|
{
|
||||||
|
json = [self NSDictionary:json];
|
||||||
|
RCTPointAnnotation *shape = [[RCTPointAnnotation alloc] init];
|
||||||
|
shape.coordinate = [self CLLocationCoordinate2D:json];
|
||||||
|
shape.title = [RCTConvert NSString:json[@"title"]];
|
||||||
|
shape.subtitle = [RCTConvert NSString:json[@"subtitle"]];
|
||||||
|
shape.identifier = [RCTConvert NSString:json[@"id"]];
|
||||||
|
shape.hasLeftCallout = [RCTConvert BOOL:json[@"hasLeftCallout"]];
|
||||||
|
shape.hasRightCallout = [RCTConvert BOOL:json[@"hasRightCallout"]];
|
||||||
|
shape.animateDrop = [RCTConvert BOOL:json[@"animateDrop"]];
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_ARRAY_CONVERTER(RCTPointAnnotation)
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -26,7 +26,8 @@ extern const CGFloat RCTMapZoomBoundBuffer;
|
|||||||
@property (nonatomic, assign) CGFloat maxDelta;
|
@property (nonatomic, assign) CGFloat maxDelta;
|
||||||
@property (nonatomic, assign) UIEdgeInsets legalLabelInsets;
|
@property (nonatomic, assign) UIEdgeInsets legalLabelInsets;
|
||||||
@property (nonatomic, strong) NSTimer *regionChangeObserveTimer;
|
@property (nonatomic, strong) NSTimer *regionChangeObserveTimer;
|
||||||
|
@property (nonatomic, strong) NSMutableArray *annotationIds;
|
||||||
|
|
||||||
- (void)setAnnotations:(MKShapeArray *)annotations;
|
- (void)setAnnotations:(RCTPointAnnotationArray *)annotations;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -112,12 +112,52 @@ const CGFloat RCTMapZoomBoundBuffer = 0.01;
|
|||||||
[super setRegion:region animated:animated];
|
[super setRegion:region animated:animated];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setAnnotations:(MKShapeArray *)annotations
|
- (void)setAnnotations:(RCTPointAnnotationArray *)annotations
|
||||||
{
|
{
|
||||||
[self removeAnnotations:self.annotations];
|
NSMutableArray *newAnnotationIds = [[NSMutableArray alloc] init];
|
||||||
if (annotations.count) {
|
NSMutableArray *annotationsToDelete = [[NSMutableArray alloc] init];
|
||||||
[self addAnnotations:annotations];
|
NSMutableArray *annotationsToAdd = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
|
for (RCTPointAnnotation *annotation in annotations) {
|
||||||
|
if (![annotation isKindOfClass:[RCTPointAnnotation class]]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
[newAnnotationIds addObject:annotation.identifier];
|
||||||
|
|
||||||
|
// If the current set does not contain the new annotation, mark it as add
|
||||||
|
if (![self.annotationIds containsObject:annotation.identifier]) {
|
||||||
|
[annotationsToAdd addObject:annotation];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (RCTPointAnnotation *annotation in self.annotations) {
|
||||||
|
if (![annotation isKindOfClass:[RCTPointAnnotation class]]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the new set does not contain an existing annotation, mark it as delete
|
||||||
|
if (![newAnnotationIds containsObject:annotation.identifier]) {
|
||||||
|
[annotationsToDelete addObject:annotation];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (annotationsToDelete.count) {
|
||||||
|
[self removeAnnotations:annotationsToDelete];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (annotationsToAdd.count) {
|
||||||
|
[self addAnnotations:annotationsToAdd];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSMutableArray *newIds = [[NSMutableArray alloc] init];
|
||||||
|
for (RCTPointAnnotation *anno in self.annotations) {
|
||||||
|
if ([anno isKindOfClass:[MKUserLocation class]]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
[newIds addObject:anno.identifier];
|
||||||
|
}
|
||||||
|
self.annotationIds = newIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
#import "RCTEventDispatcher.h"
|
#import "RCTEventDispatcher.h"
|
||||||
#import "RCTMap.h"
|
#import "RCTMap.h"
|
||||||
#import "UIView+React.h"
|
#import "UIView+React.h"
|
||||||
|
#import "RCTPointAnnotation.h"
|
||||||
|
|
||||||
|
#import <MapKit/MapKit.h>
|
||||||
|
|
||||||
static NSString *const RCTMapViewKey = @"MapView";
|
static NSString *const RCTMapViewKey = @"MapView";
|
||||||
|
|
||||||
@ -42,7 +45,7 @@ RCT_EXPORT_VIEW_PROPERTY(maxDelta, CGFloat)
|
|||||||
RCT_EXPORT_VIEW_PROPERTY(minDelta, CGFloat)
|
RCT_EXPORT_VIEW_PROPERTY(minDelta, CGFloat)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(legalLabelInsets, UIEdgeInsets)
|
RCT_EXPORT_VIEW_PROPERTY(legalLabelInsets, UIEdgeInsets)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(mapType, MKMapType)
|
RCT_EXPORT_VIEW_PROPERTY(mapType, MKMapType)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(annotations, MKShapeArray)
|
RCT_EXPORT_VIEW_PROPERTY(annotations, RCTPointAnnotationArray)
|
||||||
RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
|
RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
|
||||||
{
|
{
|
||||||
[view setRegion:json ? [RCTConvert MKCoordinateRegion:json] : defaultView.region animated:YES];
|
[view setRegion:json ? [RCTConvert MKCoordinateRegion:json] : defaultView.region animated:YES];
|
||||||
@ -50,6 +53,73 @@ RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
|
|||||||
|
|
||||||
#pragma mark MKMapViewDelegate
|
#pragma mark MKMapViewDelegate
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
|
||||||
|
{
|
||||||
|
if (![view.annotation isKindOfClass:[MKUserLocation class]]) {
|
||||||
|
|
||||||
|
RCTPointAnnotation *annotation = (RCTPointAnnotation *)view.annotation;
|
||||||
|
NSString *title = view.annotation.title ?: @"";
|
||||||
|
NSString *subtitle = view.annotation.subtitle ?: @"";
|
||||||
|
|
||||||
|
NSDictionary *event = @{
|
||||||
|
@"target": mapView.reactTag,
|
||||||
|
@"action": @"annotation-click",
|
||||||
|
@"annotation": @{
|
||||||
|
@"id": annotation.identifier,
|
||||||
|
@"title": title,
|
||||||
|
@"subtitle": subtitle,
|
||||||
|
@"latitude": @(annotation.coordinate.latitude),
|
||||||
|
@"longitude": @(annotation.coordinate.longitude)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
[self.bridge.eventDispatcher sendInputEventWithName:@"topTap" body:event];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(RCTPointAnnotation *)annotation
|
||||||
|
{
|
||||||
|
if ([annotation isKindOfClass:[MKUserLocation class]]) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
MKPinAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"RCTAnnotation"];
|
||||||
|
|
||||||
|
annotationView.canShowCallout = true;
|
||||||
|
annotationView.animatesDrop = annotation.animateDrop;
|
||||||
|
|
||||||
|
annotationView.leftCalloutAccessoryView = nil;
|
||||||
|
if (annotation.hasLeftCallout) {
|
||||||
|
annotationView.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
|
||||||
|
}
|
||||||
|
|
||||||
|
annotationView.rightCalloutAccessoryView = nil;
|
||||||
|
if (annotation.hasRightCallout) {
|
||||||
|
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
|
||||||
|
}
|
||||||
|
|
||||||
|
return annotationView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
|
||||||
|
{
|
||||||
|
// Pass to js
|
||||||
|
RCTPointAnnotation *annotation = (RCTPointAnnotation *)view.annotation;
|
||||||
|
NSString *side = (control == view.leftCalloutAccessoryView) ? @"left" : @"right";
|
||||||
|
|
||||||
|
NSDictionary *event = @{
|
||||||
|
@"target": mapView.reactTag,
|
||||||
|
@"side": side,
|
||||||
|
@"action": @"callout-click",
|
||||||
|
@"annotationId": annotation.identifier
|
||||||
|
};
|
||||||
|
|
||||||
|
[self.bridge.eventDispatcher sendInputEventWithName:@"topTap" body:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)mapView:(RCTMap *)mapView didUpdateUserLocation:(MKUserLocation *)location
|
- (void)mapView:(RCTMap *)mapView didUpdateUserLocation:(MKUserLocation *)location
|
||||||
{
|
{
|
||||||
if (mapView.followUserLocation) {
|
if (mapView.followUserLocation) {
|
||||||
@ -143,7 +213,7 @@ RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
|
|||||||
#define FLUSH_NAN(value) (isnan(value) ? 0 : value)
|
#define FLUSH_NAN(value) (isnan(value) ? 0 : value)
|
||||||
|
|
||||||
NSDictionary *event = @{
|
NSDictionary *event = @{
|
||||||
@"target": [mapView reactTag],
|
@"target": mapView.reactTag,
|
||||||
@"continuous": @(continuous),
|
@"continuous": @(continuous),
|
||||||
@"region": @{
|
@"region": @{
|
||||||
@"latitude": @(FLUSH_NAN(region.center.latitude)),
|
@"latitude": @(FLUSH_NAN(region.center.latitude)),
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
@property (nonatomic, strong) UIColor *tintColor;
|
@property (nonatomic, strong) UIColor *tintColor;
|
||||||
@property (nonatomic, strong) UIColor *barTintColor;
|
@property (nonatomic, strong) UIColor *barTintColor;
|
||||||
@property (nonatomic, strong) UIColor *titleTextColor;
|
@property (nonatomic, strong) UIColor *titleTextColor;
|
||||||
|
@property (nonatomic, assign) BOOL translucent;
|
||||||
|
|
||||||
@property (nonatomic, readonly) UIBarButtonItem *backButtonItem;
|
@property (nonatomic, readonly) UIBarButtonItem *backButtonItem;
|
||||||
@property (nonatomic, readonly) UIBarButtonItem *leftButtonItem;
|
@property (nonatomic, readonly) UIBarButtonItem *leftButtonItem;
|
||||||
|
@ -24,6 +24,7 @@ RCT_EXPORT_MODULE()
|
|||||||
RCT_EXPORT_VIEW_PROPERTY(navigationBarHidden, BOOL)
|
RCT_EXPORT_VIEW_PROPERTY(navigationBarHidden, BOOL)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor)
|
RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(barTintColor, UIColor)
|
RCT_EXPORT_VIEW_PROPERTY(barTintColor, UIColor)
|
||||||
|
RCT_EXPORT_VIEW_PROPERTY(translucent, BOOL)
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(title, NSString)
|
RCT_EXPORT_VIEW_PROPERTY(title, NSString)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(titleTextColor, UIColor)
|
RCT_EXPORT_VIEW_PROPERTY(titleTextColor, UIColor)
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
//
|
/**
|
||||||
// RCTSegmentedControl.h
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
// React
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Created by Clay Allsopp on 3/31/15.
|
* This source code is licensed under the BSD-style license found in the
|
||||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
//
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
//
|
/**
|
||||||
// RCTSegmentedControl.m
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
// React
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Created by Clay Allsopp on 3/31/15.
|
* This source code is licensed under the BSD-style license found in the
|
||||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
//
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import "RCTSegmentedControl.h"
|
#import "RCTSegmentedControl.h"
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder)
|
|||||||
UINavigationBar *bar = self.navigationController.navigationBar;
|
UINavigationBar *bar = self.navigationController.navigationBar;
|
||||||
bar.barTintColor = _navItem.barTintColor;
|
bar.barTintColor = _navItem.barTintColor;
|
||||||
bar.tintColor = _navItem.tintColor;
|
bar.tintColor = _navItem.tintColor;
|
||||||
|
bar.translucent = _navItem.translucent;
|
||||||
if (_navItem.titleTextColor) {
|
if (_navItem.titleTextColor) {
|
||||||
[bar setTitleTextAttributes:@{NSForegroundColorAttributeName : _navItem.titleTextColor}];
|
[bar setTitleTextAttributes:@{NSForegroundColorAttributeName : _navItem.titleTextColor}];
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user