mirror of
https://github.com/status-im/react-native-mapbox-gl.git
synced 2026-08-30 20:41:08 +00:00
support for custom annotation views
This commit is contained in:
@@ -0,0 +1,283 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import {
|
||||
View,
|
||||
requireNativeComponent,
|
||||
StyleSheet,
|
||||
Platform,
|
||||
NativeModules,
|
||||
Animated,
|
||||
findNodeHandle,
|
||||
} from 'react-native';
|
||||
|
||||
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
|
||||
|
||||
const viewConfig = {
|
||||
uiViewClassName: 'RCTMapboxAnnotation',
|
||||
validAttributes: {
|
||||
coordinate: true,
|
||||
},
|
||||
};
|
||||
|
||||
const propTypes = {
|
||||
...View.propTypes,
|
||||
|
||||
// TODO(lmr): get rid of these?
|
||||
identifier: PropTypes.string,
|
||||
reuseIdentifier: PropTypes.string,
|
||||
|
||||
/**
|
||||
* The title of the marker. This is only used if the <Marker /> component has no children that
|
||||
* are an `<MapView.Callout />`, in which case the default callout behavior will be used, which
|
||||
* will show both the `title` and the `description`, if provided.
|
||||
*/
|
||||
title: PropTypes.string,
|
||||
|
||||
/**
|
||||
* The title of the marker. This is only used if the <Marker /> component has no children that
|
||||
* are an `<MapView.Callout />`, in which case the default callout behavior will be used, which
|
||||
* will show both the `title` and the `description`, if provided.
|
||||
*/
|
||||
subtitle: PropTypes.string,
|
||||
|
||||
/**
|
||||
* The description of the marker. This is only used if the <Marker /> component has no children
|
||||
* that are an `<MapView.Callout />`, in which case the default callout behavior will be used,
|
||||
* which will show both the `title` and the `description`, if provided.
|
||||
*/
|
||||
description: PropTypes.string,
|
||||
|
||||
/**
|
||||
* A custom image to be used as the marker's icon. Only local image resources are allowed to be
|
||||
* used.
|
||||
*/
|
||||
image: PropTypes.any,
|
||||
|
||||
/**
|
||||
* If no custom marker view or custom image is provided, the platform default pin will be used,
|
||||
* which can be customized by this color. Ignored if a custom marker is being used.
|
||||
*/
|
||||
pinColor: PropTypes.string,
|
||||
|
||||
/**
|
||||
* The coordinate for the marker.
|
||||
*/
|
||||
coordinate: PropTypes.shape({
|
||||
/**
|
||||
* Coordinates for the anchor point of the marker.
|
||||
*/
|
||||
latitude: PropTypes.number.isRequired,
|
||||
longitude: PropTypes.number.isRequired,
|
||||
}).isRequired,
|
||||
|
||||
/**
|
||||
* The offset (in points) at which to display the view.
|
||||
*
|
||||
* By default, the center point of an annotation view is placed at the coordinate point of the
|
||||
* associated annotation. You can use this property to reposition the annotation view as
|
||||
* needed. This x and y offset values are measured in points. Positive offset values move the
|
||||
* annotation view down and to the right, while negative values move it up and to the left.
|
||||
*
|
||||
* For android, see the `anchor` prop.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
centerOffset: PropTypes.shape({
|
||||
/**
|
||||
* Offset from the anchor point
|
||||
*/
|
||||
x: PropTypes.number.isRequired,
|
||||
y: PropTypes.number.isRequired,
|
||||
}),
|
||||
|
||||
/**
|
||||
* The offset (in points) at which to place the callout bubble.
|
||||
*
|
||||
* This property determines the additional distance by which to move the callout bubble. When
|
||||
* this property is set to (0, 0), the anchor point of the callout bubble is placed on the
|
||||
* top-center point of the marker view’s frame. Specifying positive offset values moves the
|
||||
* callout bubble down and to the right, while specifying negative values moves it up and to
|
||||
* the left.
|
||||
*
|
||||
* For android, see the `calloutAnchor` prop.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
calloutOffset: PropTypes.shape({
|
||||
/**
|
||||
* Offset to the callout
|
||||
*/
|
||||
x: PropTypes.number.isRequired,
|
||||
y: PropTypes.number.isRequired,
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sets the anchor point for the marker.
|
||||
*
|
||||
* The anchor specifies the point in the icon image that is anchored to the marker's position
|
||||
* on the Earth's surface.
|
||||
*
|
||||
* The anchor point is specified in the continuous space [0.0, 1.0] x [0.0, 1.0], where (0, 0)
|
||||
* is the top-left corner of the image, and (1, 1) is the bottom-right corner. The anchoring
|
||||
* point in a W x H image is the nearest discrete grid point in a (W + 1) x (H + 1) grid,
|
||||
* obtained by scaling the then rounding. For example, in a 4 x 2 image, the anchor point
|
||||
* (0.7, 0.6) resolves to the grid point at (3, 1).
|
||||
*
|
||||
* For ios, see the `centerOffset` prop.
|
||||
*
|
||||
* @platform android
|
||||
*/
|
||||
anchor: PropTypes.shape({
|
||||
/**
|
||||
* Offset to the callout
|
||||
*/
|
||||
x: PropTypes.number.isRequired,
|
||||
y: PropTypes.number.isRequired,
|
||||
}),
|
||||
|
||||
/**
|
||||
* Specifies the point in the marker image at which to anchor the callout when it is displayed.
|
||||
* This is specified in the same coordinate system as the anchor. See the `andor` prop for more
|
||||
* details.
|
||||
*
|
||||
* The default is the top middle of the image.
|
||||
*
|
||||
* For ios, see the `calloutOffset` prop.
|
||||
*
|
||||
* @platform android
|
||||
*/
|
||||
calloutAnchor: PropTypes.shape({
|
||||
/**
|
||||
* Offset to the callout
|
||||
*/
|
||||
x: PropTypes.number.isRequired,
|
||||
y: PropTypes.number.isRequired,
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sets whether this marker should be flat against the map true or a billboard facing the
|
||||
* camera false.
|
||||
*
|
||||
* @platform android
|
||||
*/
|
||||
flat: PropTypes.bool,
|
||||
|
||||
draggable: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* Callback that is called when the user presses on the marker
|
||||
*/
|
||||
onPress: PropTypes.func,
|
||||
|
||||
/**
|
||||
* Callback that is called when the user selects the marker, before the callout is shown.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
onSelect: PropTypes.func,
|
||||
|
||||
/**
|
||||
* Callback that is called when the marker is deselected, before the callout is hidden.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
onDeselect: PropTypes.func,
|
||||
|
||||
/**
|
||||
* Callback that is called when the user taps the callout view.
|
||||
*/
|
||||
onCalloutPress: PropTypes.func,
|
||||
|
||||
/**
|
||||
* Callback that is called when the user initiates a drag on this marker (if it is draggable)
|
||||
*/
|
||||
onDragStart: PropTypes.func,
|
||||
|
||||
/**
|
||||
* Callback called continuously as the marker is dragged
|
||||
*/
|
||||
onDrag: PropTypes.func,
|
||||
|
||||
/**
|
||||
* Callback that is called when a drag on this marker finishes. This is usually the point you
|
||||
* will want to setState on the marker's coordinate again
|
||||
*/
|
||||
onDragEnd: PropTypes.func,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
onPress() {},
|
||||
};
|
||||
|
||||
class MapboxAnnotation extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.showCallout = this.showCallout.bind(this);
|
||||
this.hideCallout = this.hideCallout.bind(this);
|
||||
}
|
||||
|
||||
showCallout() {
|
||||
this._runCommand('showCallout', []);
|
||||
}
|
||||
|
||||
hideCallout() {
|
||||
this._runCommand('hideCallout', []);
|
||||
}
|
||||
|
||||
_getHandle() {
|
||||
return findNodeHandle(this.marker);
|
||||
}
|
||||
|
||||
_runCommand(name, args) {
|
||||
switch (Platform.OS) {
|
||||
case 'android':
|
||||
NativeModules.UIManager.dispatchViewManagerCommand(
|
||||
this._getHandle(),
|
||||
NativeModules.UIManager.RCTMapboxAnnotation.Commands[name],
|
||||
args
|
||||
);
|
||||
break;
|
||||
|
||||
case 'ios':
|
||||
NativeModules.RCTMapboxAnnotationManager[name].apply(
|
||||
NativeModules.RCTMapboxAnnotationManager[name],
|
||||
[this._getHandle(), ...args]
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let image;
|
||||
if (this.props.image) {
|
||||
image = resolveAssetSource(this.props.image) || {};
|
||||
image = image.uri;
|
||||
}
|
||||
|
||||
return (
|
||||
<RCTMapboxAnnotation
|
||||
ref={ref => { this.marker = ref; }}
|
||||
{...this.props}
|
||||
image={image}
|
||||
style={[styles.marker, this.props.style]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MapboxAnnotation.propTypes = propTypes;
|
||||
MapboxAnnotation.defaultProps = defaultProps;
|
||||
MapboxAnnotation.viewConfig = viewConfig;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
marker: {
|
||||
position: 'absolute',
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
});
|
||||
|
||||
const RCTMapboxAnnotation = requireNativeComponent('RCTMapboxAnnotation', MapboxAnnotation);
|
||||
module.exports = MapboxAnnotation;
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import clone from 'lodash/clone';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import Annotation from './MapboxAnnotation';
|
||||
|
||||
const { MapboxGLManager } = NativeModules;
|
||||
const { mapStyles, userTrackingMode, userLocationVerticalAlignment, unknownResourceCount } = MapboxGLManager;
|
||||
@@ -438,6 +439,7 @@ const MapboxGLView = requireNativeComponent('RCTMapboxGL', MapView, {
|
||||
|
||||
const Mapbox = {
|
||||
MapView,
|
||||
Annotation,
|
||||
mapStyles, userTrackingMode, userLocationVerticalAlignment, unknownResourceCount,
|
||||
getMetricsEnabled, setMetricsEnabled,
|
||||
setAccessToken,
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
874C0C441D9436D80034AF3F /* RCTMapboxAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 874C0C401D9436D80034AF3F /* RCTMapboxAnnotation.m */; };
|
||||
874C0C451D9436D80034AF3F /* RCTMapboxAnnotationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 874C0C421D9436D80034AF3F /* RCTMapboxAnnotationManager.m */; };
|
||||
C167F89C1D18112B007C7A42 /* RCTMapboxGLConversions.m in Sources */ = {isa = PBXBuildFile; fileRef = C167F89B1D18112B007C7A42 /* RCTMapboxGLConversions.m */; };
|
||||
C5DBB3441AF2EF2B00E611A9 /* RCTMapboxGL.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C5DBB3431AF2EF2B00E611A9 /* RCTMapboxGL.h */; };
|
||||
C5DBB3461AF2EF2B00E611A9 /* RCTMapboxGL.m in Sources */ = {isa = PBXBuildFile; fileRef = C5DBB3451AF2EF2B00E611A9 /* RCTMapboxGL.m */; };
|
||||
@@ -38,6 +40,10 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
874C0C401D9436D80034AF3F /* RCTMapboxAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMapboxAnnotation.m; sourceTree = "<group>"; };
|
||||
874C0C411D9436D80034AF3F /* RCTMapboxAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMapboxAnnotation.h; sourceTree = "<group>"; };
|
||||
874C0C421D9436D80034AF3F /* RCTMapboxAnnotationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMapboxAnnotationManager.m; sourceTree = "<group>"; };
|
||||
874C0C431D9436D80034AF3F /* RCTMapboxAnnotationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMapboxAnnotationManager.h; sourceTree = "<group>"; };
|
||||
C167F89A1D18111F007C7A42 /* RCTMapboxGLConversions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTMapboxGLConversions.h; sourceTree = "<group>"; };
|
||||
C167F89B1D18112B007C7A42 /* RCTMapboxGLConversions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMapboxGLConversions.m; sourceTree = "<group>"; };
|
||||
C5DBB3401AF2EF2B00E611A9 /* libRCTMapboxGL.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTMapboxGL.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -89,6 +95,10 @@
|
||||
C5DBB3421AF2EF2B00E611A9 /* RCTMapboxGL */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
874C0C401D9436D80034AF3F /* RCTMapboxAnnotation.m */,
|
||||
874C0C411D9436D80034AF3F /* RCTMapboxAnnotation.h */,
|
||||
874C0C421D9436D80034AF3F /* RCTMapboxAnnotationManager.m */,
|
||||
874C0C431D9436D80034AF3F /* RCTMapboxAnnotationManager.h */,
|
||||
C5DBB3431AF2EF2B00E611A9 /* RCTMapboxGL.h */,
|
||||
C5DBB3451AF2EF2B00E611A9 /* RCTMapboxGL.m */,
|
||||
C5DBB3641AF2EFB500E611A9 /* RCTMapboxGLManager.h */,
|
||||
@@ -206,6 +216,8 @@
|
||||
C5DBB3461AF2EF2B00E611A9 /* RCTMapboxGL.m in Sources */,
|
||||
C5DBB3661AF2EFB500E611A9 /* RCTMapboxGLManager.m in Sources */,
|
||||
C167F89C1D18112B007C7A42 /* RCTMapboxGLConversions.m in Sources */,
|
||||
874C0C451D9436D80034AF3F /* RCTMapboxAnnotationManager.m in Sources */,
|
||||
874C0C441D9436D80034AF3F /* RCTMapboxAnnotation.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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 "RCTMapboxAnnotation.h"
|
||||
|
||||
#import <MapBox/MapBox.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "RCTConvert+MapKit.h"
|
||||
#import "RCTComponent.h"
|
||||
#import "RCTMapboxGL.h"
|
||||
|
||||
@class RCTBridge;
|
||||
|
||||
@interface RCTMapboxAnnotation : MGLAnnotationView <MGLAnnotation>
|
||||
|
||||
@property (nonatomic, weak, nullable) RCTMapboxGL *map;
|
||||
@property (nonatomic, weak, nullable) RCTBridge *bridge;
|
||||
/**
|
||||
The center point (specified as a map coordinate) of the annotation. (required)
|
||||
(read-only)
|
||||
*/
|
||||
@property (nonatomic) CLLocationCoordinate2D coordinate;
|
||||
|
||||
/**
|
||||
The string containing the annotation’s title.
|
||||
|
||||
Although this property is optional, if you support the selection of annotations
|
||||
in your map view, you are expected to provide this property. This string is
|
||||
displayed in the callout for the associated annotation.
|
||||
*/
|
||||
@property (nonatomic, copy, nullable) NSString *title;
|
||||
|
||||
/**
|
||||
The string containing the annotation’s subtitle.
|
||||
|
||||
This string is displayed in the callout for the associated annotation.
|
||||
*/
|
||||
@property (nonatomic, copy, nullable) NSString *subtitle;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 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 "RCTMapboxAnnotation.h"
|
||||
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import "UIView+React.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
@implementation RCTMapboxAnnotation {
|
||||
}
|
||||
-(void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
[self.map layoutIfNeeded];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -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 "RCTViewManager.h"
|
||||
|
||||
@interface RCTMapboxAnnotationManager : RCTViewManager
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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 "RCTMapboxAnnotationManager.h"
|
||||
|
||||
#import "RCTUIManager.h"
|
||||
#import "RCTConvert+CoreLocation.h"
|
||||
#import "UIView+React.h"
|
||||
#import "RCTMapboxAnnotation.h"
|
||||
|
||||
@interface RCTMapboxAnnotationManager () <MGLMapViewDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTMapboxAnnotationManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
RCTMapboxAnnotation *marker = [RCTMapboxAnnotation new];
|
||||
// UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_handleTap:)];
|
||||
// // setting this to NO allows the parent MapView to continue receiving marker selection events
|
||||
// tapGestureRecognizer.cancelsTouchesInView = NO;
|
||||
// [marker addGestureRecognizer:tapGestureRecognizer];
|
||||
marker.bridge = self.bridge;
|
||||
return marker;
|
||||
}
|
||||
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(title, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(subtitle, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(coordinate, CLLocationCoordinate2D)
|
||||
|
||||
@end
|
||||
@@ -12,6 +12,7 @@
|
||||
#import "UIView+React.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTMapboxGLConversions.h"
|
||||
#import "RCTMapboxAnnotation.h"
|
||||
|
||||
@implementation RCTMapboxGL {
|
||||
/* Required to publish events */
|
||||
@@ -42,6 +43,16 @@
|
||||
MGLAnnotationVerticalAlignment _userLocationVerticalAlignment;
|
||||
/* So we don't fire onChangeUserTracking mode when triggered by props */
|
||||
BOOL _isChangingUserTracking;
|
||||
// Array to manually track RN subviews
|
||||
//
|
||||
// AIRMap implicitly creates subviews that aren't regular RN children
|
||||
// (SMCalloutView injects an overlay subview), which otherwise confuses RN
|
||||
// during component re-renders:
|
||||
// https://github.com/facebook/react-native/blob/v0.16.0/React/Modules/RCTUIManager.m#L657
|
||||
//
|
||||
// Implementation based on RCTTextField, another component with indirect children
|
||||
// https://github.com/facebook/react-native/blob/v0.16.0/Libraries/Text/RCTTextField.m#L20
|
||||
NSMutableArray<UIView *> *_reactSubviews;
|
||||
}
|
||||
|
||||
// View creation
|
||||
@@ -122,8 +133,35 @@
|
||||
[self createMapIfNeeded];
|
||||
}
|
||||
_map.frame = self.bounds;
|
||||
[_map layoutIfNeeded];
|
||||
}
|
||||
|
||||
// React subviews for custom annotation management
|
||||
- (void)insertReactSubview:(id<RCTComponent>)subview atIndex:(NSInteger)atIndex {
|
||||
// Our desired API is to pass up markers/overlays as children to the mapview component.
|
||||
// This is where we intercept them and do the appropriate underlying mapview action.
|
||||
if ([subview isKindOfClass:[RCTMapboxAnnotation class]]) {
|
||||
((RCTMapboxAnnotation *) subview).map = self;
|
||||
[_map addAnnotation:(id <MGLAnnotation>) subview];
|
||||
}
|
||||
[_reactSubviews insertObject:(UIView *)subview atIndex:(NSUInteger) atIndex];
|
||||
}
|
||||
|
||||
- (void)removeReactSubview:(id<RCTComponent>)subview {
|
||||
// similarly, when the children are being removed we have to do the appropriate
|
||||
// underlying mapview action here.
|
||||
if ([subview isKindOfClass:[RCTMapboxAnnotation class]]) {
|
||||
[self removeAnnotation:(id<MGLAnnotation>)subview];
|
||||
}
|
||||
[_reactSubviews removeObject:(UIView *)subview];
|
||||
}
|
||||
|
||||
- (NSArray<id<RCTComponent>> *)reactSubviews {
|
||||
return _reactSubviews;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Annotation management
|
||||
|
||||
- (void)upsertAnnotation:(RCTMGLAnnotation *) annotation {
|
||||
@@ -203,6 +241,13 @@
|
||||
return ([title length] != 0 || [subtitle length] != 0);
|
||||
}
|
||||
|
||||
- (nullable MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id <MGLAnnotation>)annotation {
|
||||
if ([annotation isKindOfClass:[RCTMapboxAnnotation class]]){
|
||||
return annotation;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (UIButton *)mapView:(MGLMapView *)mapView rightCalloutAccessoryViewForAnnotation:(id <MGLAnnotation>)annotation;
|
||||
{
|
||||
if ([annotation isKindOfClass:[RCTMGLAnnotation class]]) {
|
||||
|
||||
Reference in New Issue
Block a user