Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MapView annotation callback when it gets / lost the focus #5167

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Examples/UIExplorer/MapViewExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,20 @@ exports.examples = [
}}/>;
}
},
{
title: 'Annotation focus example',
render() {
return <AnnotationExample style={styles.map} annotation={{
title: 'More Info...',
onFocus: () => {
alert('Annotation gets focus');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-alert: Unexpected alert.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-undef: "alert" is not defined.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-undef: "alert" is not defined.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-alert: Unexpected alert.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-alert: Unexpected alert.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-undef: "alert" is not defined.

},
onBlur: () => {
alert('Annotation lost focus');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-alert: Unexpected alert.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-undef: "alert" is not defined.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-alert: Unexpected alert.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-undef: "alert" is not defined.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-undef: "alert" is not defined.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-alert: Unexpected alert.

}
}}/>;
}
},
{
title: 'Draggable pin',
render() {
Expand Down
96 changes: 61 additions & 35 deletions Libraries/Components/MapView/MapView.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,21 @@ const MapView = React.createClass({

/**
* Event that fires when the annotation drag state changes.
*/
*/
onDragStateChange: React.PropTypes.func,

/**
* Event that fires when the annotation gets was tapped by the user
* and the callout view was displayed.
*/
onFocus: React.PropTypes.func,

/**
* Event that fires when another annotation or the mapview itself
* was tapped and a previously shown annotation will be closed.
*/
onBlur: React.PropTypes.func,

/**
* Annotation title/subtile.
*/
Expand Down Expand Up @@ -276,7 +288,7 @@ const MapView = React.createClass({
onRegionChangeComplete: React.PropTypes.func,

/**
* Callback that is called once, when the user taps an annotation.
* Deprecated. Use annotation onFocus and onBlur instead.
*/
onAnnotationPress: React.PropTypes.func,

Expand Down Expand Up @@ -375,51 +387,61 @@ const MapView = React.createClass({
return result;
});

const findByAnnotationId = (annotationId: string) => {
if (!annotations) {
return null;
}
for (let i = 0, l = annotations.length; i < l; i++) {
if (annotations[i].id === annotationId) {
return annotations[i];
}
}
return null;
};

// TODO: these should be separate events, to reduce bridge traffic
let onPress, onAnnotationDragStateChange, onAnnotationFocus, onAnnotationBlur;
if (annotations) {
var onPress = (event: Event) => {
if (!annotations) {
return;
}
onPress = (event: Event) => {
if (event.nativeEvent.action === 'annotation-click') {
// TODO: Remove deprecated onAnnotationPress API call later.
this.props.onAnnotationPress &&
this.props.onAnnotationPress(event.nativeEvent.annotation);
} else if (event.nativeEvent.action === 'callout-click') {
// Find the annotation with the id that was pressed
for (let i = 0, l = annotations.length; i < l; i++) {
let annotation = 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);
}
break;
const annotation = findByAnnotationId(event.nativeEvent.annotationId);
if (annotation) {
// 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);
}
}
}
};
var onAnnotationDragStateChange = (event: Event) => {
if (!annotations) {
return;
onAnnotationDragStateChange = (event: Event) => {
const annotation = findByAnnotationId(event.nativeEvent.annotationId);
if (annotation) {
// Update location
annotation.latitude = event.nativeEvent.latitude;
annotation.longitude = event.nativeEvent.longitude;
// Call callback
annotation.onDragStateChange &&
annotation.onDragStateChange(event.nativeEvent);
}
// Find the annotation with the id that was pressed
for (let i = 0, l = annotations.length; i < l; i++) {
let annotation = annotations[i];
if (annotation.id === event.nativeEvent.annotationId) {
// Update location
annotation.latitude = event.nativeEvent.latitude;
annotation.longitude = event.nativeEvent.longitude;
// Call callback
annotation.onDragStateChange &&
annotation.onDragStateChange(event.nativeEvent);
break;
}
};
onAnnotationFocus = (event: Event) => {
const annotation = findByAnnotationId(event.nativeEvent.annotationId);
if (annotation && annotation.onFocus) {
annotation.onFocus(event.nativeEvent);
}
}
};
onAnnotationBlur = (event: Event) => {
const annotation = findByAnnotationId(event.nativeEvent.annotationId);
if (annotation && annotation.onBlur) {
annotation.onBlur(event.nativeEvent);
}
};
}

// TODO: these should be separate events, to reduce bridge traffic
Expand Down Expand Up @@ -450,6 +472,8 @@ const MapView = React.createClass({
onPress={onPress}
onChange={onChange}
onAnnotationDragStateChange={onAnnotationDragStateChange}
onAnnotationFocus={onAnnotationFocus}
onAnnotationBlur={onAnnotationBlur}
/>
);
},
Expand Down Expand Up @@ -483,6 +507,8 @@ MapView.PinColors = PinColors && {
const RCTMap = requireNativeComponent('RCTMap', MapView, {
nativeOnly: {
onAnnotationDragStateChange: true,
onAnnotationFocus: true,
onAnnotationBlur: true,
onChange: true,
onPress: true
}
Expand Down
2 changes: 2 additions & 0 deletions React/Views/RCTMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ RCT_EXTERN const CGFloat RCTMapZoomBoundBuffer;
@property (nonatomic, copy) RCTBubblingEventBlock onChange;
@property (nonatomic, copy) RCTBubblingEventBlock onPress;
@property (nonatomic, copy) RCTBubblingEventBlock onAnnotationDragStateChange;
@property (nonatomic, copy) RCTBubblingEventBlock onAnnotationFocus;
@property (nonatomic, copy) RCTBubblingEventBlock onAnnotationBlur;

- (void)setAnnotations:(NSArray<RCTMapAnnotation *> *)annotations;
- (void)setOverlays:(NSArray<RCTMapOverlay *> *)overlays;
Expand Down
24 changes: 24 additions & 0 deletions React/Views/RCTMapManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(annotations, NSArray<RCTMapAnnotation *>)
RCT_EXPORT_VIEW_PROPERTY(overlays, NSArray<RCTMapOverlay *>)
RCT_EXPORT_VIEW_PROPERTY(onAnnotationDragStateChange, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onAnnotationFocus, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onAnnotationBlur, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock)
RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
Expand Down Expand Up @@ -137,6 +139,7 @@ - (UIView *)view

- (void)mapView:(RCTMap *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
// TODO: Remove deprecated onAnnotationPress API call later.
if (mapView.onPress && [view.annotation isKindOfClass:[RCTMapAnnotation class]]) {
RCTMapAnnotation *annotation = (RCTMapAnnotation *)view.annotation;
mapView.onPress(@{
Expand All @@ -150,6 +153,27 @@ - (void)mapView:(RCTMap *)mapView didSelectAnnotationView:(MKAnnotationView *)vi
}
});
}

if ([view.annotation isKindOfClass:[RCTMapAnnotation class]]) {
RCTMapAnnotation *annotation = (RCTMapAnnotation *)view.annotation;
if (mapView.onAnnotationFocus) {
mapView.onAnnotationFocus(@{
@"annotationId": annotation.identifier
});
}
}
}

- (void)mapView:(RCTMap *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
if ([view.annotation isKindOfClass:[RCTMapAnnotation class]]) {
RCTMapAnnotation *annotation = (RCTMapAnnotation *)view.annotation;
if (mapView.onAnnotationBlur) {
mapView.onAnnotationBlur(@{
@"annotationId": annotation.identifier
});
}
}
}

- (void)mapView:(RCTMap *)mapView annotationView:(MKAnnotationView *)view
Expand Down