diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | gyp/platform-ios.gypi | 3 | ||||
-rw-r--r-- | include/mbgl/ios/MGLCalloutViewProtocol.h | 35 | ||||
-rw-r--r-- | include/mbgl/ios/MGLMapView.h | 16 | ||||
-rw-r--r-- | include/mbgl/ios/Mapbox.h | 3 | ||||
-rw-r--r-- | platform/ios/src/MGLCalloutView.h | 6 | ||||
-rw-r--r-- | platform/ios/src/MGLCalloutView.m | 5 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 24 |
8 files changed, 81 insertions, 12 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 91f094bc2e..e321f9b349 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Known issues: - The map will now snap to north. ([#3403](https://github.com/mapbox/mapbox-gl-native/pull/3403)) - The map view’s background can now be transparent or translucent, as long as the style’s background layer is transparent or translucent and `MGLMapView.opaque` is set to `NO`. ([#3096](https://github.com/mapbox/mapbox-gl-native/pull/3096)) - Documentation is now generated by [jazzy](https://github.com/realm/jazzy) instead of appledoc. ♪♫ ([#3203](https://github.com/mapbox/mapbox-gl-native/pull/3203)) +- New API to provide a custom callout view to the map for annotations. ([#3456](https://github.com/mapbox/mapbox-gl-native/pull/3456)) ## iOS 3.0.1 diff --git a/gyp/platform-ios.gypi b/gyp/platform-ios.gypi index fd3b6aa929..e3e2758128 100644 --- a/gyp/platform-ios.gypi +++ b/gyp/platform-ios.gypi @@ -68,6 +68,9 @@ '../include/mbgl/ios/MGLAnnotationImage.h', '../platform/ios/src/MGLAnnotationImage_Private.h', '../platform/ios/src/MGLAnnotationImage.m', + '../include/mbgl/ios/MGLCalloutViewProtocol.h', + '../platform/ios/src/MGLCalloutView.h', + '../platform/ios/src/MGLCalloutView.m', '../platform/ios/src/MGLCategoryLoader.h', '../platform/ios/src/MGLCategoryLoader.m', '../platform/ios/src/NSBundle+MGLAdditions.h', diff --git a/include/mbgl/ios/MGLCalloutViewProtocol.h b/include/mbgl/ios/MGLCalloutViewProtocol.h new file mode 100644 index 0000000000..590a298d71 --- /dev/null +++ b/include/mbgl/ios/MGLCalloutViewProtocol.h @@ -0,0 +1,35 @@ +#import <Foundation/Foundation.h> + +#import "MGLTypes.h" + +NS_ASSUME_NONNULL_BEGIN + +@protocol MGLCalloutViewDelegate; + +@protocol MGLCalloutViewProtocol <NSObject> + +@property (nonatomic, copy) NSString *title, *subtitle; +@property (nonatomic, strong) UIView *leftAccessoryView, *rightAccessoryView; +@property (nonatomic, weak) id<MGLCalloutViewDelegate> delegate; + +// Presents a callout view by adding it to "inView" and pointing at the given rect of inView's bounds. +// Constrains the callout to the bounds of the given view. +- (void)presentCalloutFromRect:(CGRect)rect inView:(UIView *)view constrainedToView:(UIView *)constrainedView animated:(BOOL)animated; + +- (void)dismissCalloutAnimated:(BOOL)animated; + +@end + + +@protocol MGLCalloutViewDelegate <NSObject> + +@optional +// Controls whether the callout "highlights" when pressed. default YES. You must also respond to `-calloutViewClicked` below. +- (BOOL)calloutViewShouldHighlight:(UIView<MGLCalloutViewProtocol> *)calloutView; + +// Called when the callout view is clicked. +- (void)calloutViewClicked:(UIView<MGLCalloutViewProtocol> *)calloutView; + +@end + +NS_ASSUME_NONNULL_END
\ No newline at end of file diff --git a/include/mbgl/ios/MGLMapView.h b/include/mbgl/ios/MGLMapView.h index 8ded5bf7fd..589e62a2f9 100644 --- a/include/mbgl/ios/MGLMapView.h +++ b/include/mbgl/ios/MGLMapView.h @@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN @protocol MGLMapViewDelegate; @protocol MGLAnnotation; @protocol MGLOverlay; +@protocol MGLCalloutViewProtocol; /** An interactive, customizable map view with an interface similar to the one @@ -962,7 +963,18 @@ IB_DESIGNABLE - (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id <MGLAnnotation>)annotation; /** - Return the view to display on the left side of the standard callout bubble. + Returns a custom callout view to display for the specified annotation. + + If the method is present in the delegate, it must return a new instance of a view dedicated to display the callout bubble. It will be configured by the map view. + + @param mapView The map view that requested the callout view. + @param annotation The object representing the annotation. + @return A view following the MGLCalloutView protocol. + */ +- (nullable UIView <MGLCalloutViewProtocol> *)mapView:(MGLMapView *)mapView customCalloutViewForAnnotation:(id <MGLAnnotation>)annotation; + +/** + Returns the view to display on the left side of the standard callout bubble. The default value is treated as if `nil`. The left callout view is typically used to display information about the annotation or to link to custom information provided by your application. @@ -975,7 +987,7 @@ IB_DESIGNABLE - (nullable UIView *)mapView:(MGLMapView *)mapView leftCalloutAccessoryViewForAnnotation:(id <MGLAnnotation>)annotation; /** - Return the view to display on the right side of the standard callout bubble. + Returns the view to display on the right side of the standard callout bubble. The default value is treated is if `nil`. The right callout view is typically used to link to more detailed information about the annotation. A common view to specify for this property is `UIButton` object whose type is set to `UIButtonTypeDetailDisclosure`. diff --git a/include/mbgl/ios/Mapbox.h b/include/mbgl/ios/Mapbox.h index e8b3ead1d9..70eebeeab4 100644 --- a/include/mbgl/ios/Mapbox.h +++ b/include/mbgl/ios/Mapbox.h @@ -1,8 +1,9 @@ #import "MGLAccountManager.h" #import "MGLAnnotation.h" #import "MGLAnnotationImage.h" -#import "MGLMapCamera.h" +#import "MGLCalloutViewProtocol.h" #import "MGLGeometry.h" +#import "MGLMapCamera.h" #import "MGLMapView.h" #import "MGLMapView+IBAdditions.h" #import "MGLMapView+MGLCustomStyleLayerAdditions.h" diff --git a/platform/ios/src/MGLCalloutView.h b/platform/ios/src/MGLCalloutView.h new file mode 100644 index 0000000000..aa5cb95b57 --- /dev/null +++ b/platform/ios/src/MGLCalloutView.h @@ -0,0 +1,6 @@ +#import "SMCalloutView.h" +#import "MGLCalloutViewProtocol.h" + +@interface MGLCalloutView : SMCalloutView <MGLCalloutViewProtocol> + +@end diff --git a/platform/ios/src/MGLCalloutView.m b/platform/ios/src/MGLCalloutView.m new file mode 100644 index 0000000000..8fc7cdc08d --- /dev/null +++ b/platform/ios/src/MGLCalloutView.m @@ -0,0 +1,5 @@ +#import "MGLCalloutView.h" + +@implementation MGLCalloutView + +@end diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 0f969e494c..ce42fefe3f 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -39,8 +39,7 @@ #import "MGLAccountManager_Private.h" #import "MGLAnnotationImage_Private.h" #import "MGLMapboxEvents.h" - -#import "SMCalloutView.h" +#import "MGLCalloutView.h" #import <algorithm> #import <cstdlib> @@ -118,7 +117,7 @@ public: GLKViewDelegate, CLLocationManagerDelegate, UIActionSheetDelegate, - SMCalloutViewDelegate, + MGLCalloutViewDelegate, MGLMultiPointDelegate, MGLAnnotationImageDelegate> @@ -139,7 +138,7 @@ public: /// Mapping from reusable identifiers to annotation images. @property (nonatomic) NS_MUTABLE_DICTIONARY_OF(NSString *, MGLAnnotationImage *) *annotationImagesByIdentifier; /// Currently shown popover representing the selected annotation. -@property (nonatomic) SMCalloutView *calloutViewForSelectedAnnotation; +@property (nonatomic) UIView<MGLCalloutViewProtocol> *calloutViewForSelectedAnnotation; @property (nonatomic) MGLUserLocationAnnotationView *userLocationAnnotationView; @property (nonatomic) CLLocationManager *locationManager; @property (nonatomic) CGPoint centerPoint; @@ -1342,12 +1341,12 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration) } } -- (BOOL)calloutViewShouldHighlight:(__unused SMCalloutView *)calloutView +- (BOOL)calloutViewShouldHighlight:(__unused MGLCalloutView *)calloutView { return [self.delegate respondsToSelector:@selector(mapView:tapOnCalloutForAnnotation:)]; } -- (void)calloutViewClicked:(__unused SMCalloutView *)calloutView +- (void)calloutViewClicked:(__unused MGLCalloutView *)calloutView { if ([self.delegate respondsToSelector:@selector(mapView:tapOnCalloutForAnnotation:)]) { @@ -2515,7 +2514,14 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration) [self.delegate mapView:self annotationCanShowCallout:annotation]) { // build the callout - self.calloutViewForSelectedAnnotation = [self calloutViewForAnnotation:annotation]; + if ([self.delegate respondsToSelector:@selector(mapView:customCalloutViewForAnnotation:)]) + { + self.calloutViewForSelectedAnnotation = [self.delegate mapView:self customCalloutViewForAnnotation:annotation]; + } + if (!self.calloutViewForSelectedAnnotation) + { + self.calloutViewForSelectedAnnotation = [self calloutViewForAnnotation:annotation]; + } if (_userLocationAnnotationIsSelected) { @@ -2570,9 +2576,9 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration) } } -- (SMCalloutView *)calloutViewForAnnotation:(id <MGLAnnotation>)annotation +- (MGLCalloutView *)calloutViewForAnnotation:(id <MGLAnnotation>)annotation { - SMCalloutView *calloutView = [SMCalloutView platformCalloutView]; + MGLCalloutView *calloutView = (MGLCalloutView *)[MGLCalloutView platformCalloutView]; if ([annotation respondsToSelector:@selector(title)]) calloutView.title = annotation.title; if ([annotation respondsToSelector:@selector(subtitle)]) calloutView.subtitle = annotation.subtitle; |