summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wray <jason@mapbox.com>2016-05-04 06:25:02 -0400
committerJason Wray <jason@mapbox.com>2016-07-26 18:28:02 -0700
commitee85e7d2c2d4639d2bd236dbf3f549f4343b0b27 (patch)
tree4f2f172bd20051f7de99cc0ded6d451b74c9c404
parentb3c914fb3f52f6a2b96d663f1c57c97c34eb5e23 (diff)
downloadqtlocation-mapboxgl-ee85e7d2c2d4639d2bd236dbf3f549f4343b0b27.tar.gz
[ios] Replace SMCalloutView with custom callout
New callout uses https://www.mapbox.com/ios-sdk/examples/custom-callout/ as a placeholder.
-rw-r--r--.gitmodules4
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj19
-rw-r--r--platform/ios/src/MGLCalloutView.h1
-rw-r--r--platform/ios/src/MGLCompactCalloutView.h10
-rw-r--r--platform/ios/src/MGLCompactCalloutView.m155
-rw-r--r--platform/ios/src/MGLMapView.mm5
m---------platform/ios/vendor/SMCalloutView0
7 files changed, 151 insertions, 43 deletions
diff --git a/.gitmodules b/.gitmodules
index 8eea444671..1e0c7ba3a9 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,10 +2,6 @@
path = .mason
url = https://github.com/mapbox/mason.git
-[submodule "platform/ios/vendor/SMCalloutView"]
- path = platform/ios/vendor/SMCalloutView
- url = https://github.com/nfarina/calloutview.git
-
[submodule "platform/ios/uitest/KIF"]
path = platform/ios/uitest/KIF
url = https://github.com/kif-framework/KIF.git
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index c9f7821e8f..98fc92f3de 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -153,8 +153,6 @@
DA8848851CBB033F00AB86E3 /* FABKitProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848811CBB033F00AB86E3 /* FABKitProtocol.h */; };
DA8848861CBB033F00AB86E3 /* Fabric+FABKits.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848821CBB033F00AB86E3 /* Fabric+FABKits.h */; };
DA8848871CBB033F00AB86E3 /* Fabric.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848831CBB033F00AB86E3 /* Fabric.h */; };
- DA88488B1CBB037E00AB86E3 /* SMCalloutView.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848891CBB037E00AB86E3 /* SMCalloutView.h */; };
- DA88488C1CBB037E00AB86E3 /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88488A1CBB037E00AB86E3 /* SMCalloutView.m */; };
DA88488E1CBB047F00AB86E3 /* reachability.h in Headers */ = {isa = PBXBuildFile; fileRef = DA88488D1CBB047F00AB86E3 /* reachability.h */; };
DA8848901CBB048E00AB86E3 /* reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88488F1CBB048E00AB86E3 /* reachability.m */; };
DA8933A31CCC95B000E68420 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DA89339F1CCC951200E68420 /* Localizable.strings */; };
@@ -209,7 +207,6 @@
DAA4E4321CBB730400178DFB /* MGLMapView.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88484A1CBAFB9800AB86E3 /* MGLMapView.mm */; };
DAA4E4331CBB730400178DFB /* MGLUserLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88484C1CBAFB9800AB86E3 /* MGLUserLocation.m */; };
DAA4E4341CBB730400178DFB /* MGLUserLocationAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88484E1CBAFB9800AB86E3 /* MGLUserLocationAnnotationView.m */; };
- DAA4E4351CBB730400178DFB /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88488A1CBB037E00AB86E3 /* SMCalloutView.m */; };
DAABF73D1CBC59BB005B1825 /* libmbgl-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAABF73B1CBC59BB005B1825 /* libmbgl-core.a */; };
DAABF73E1CBC59BB005B1825 /* libmbgl-platform-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAABF73C1CBC59BB005B1825 /* libmbgl-platform-ios.a */; };
DABCABAC1CB80692000A7C39 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DABCABAB1CB80692000A7C39 /* main.m */; };
@@ -476,8 +473,6 @@
DA8848811CBB033F00AB86E3 /* FABKitProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FABKitProtocol.h; sourceTree = "<group>"; };
DA8848821CBB033F00AB86E3 /* Fabric+FABKits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Fabric+FABKits.h"; sourceTree = "<group>"; };
DA8848831CBB033F00AB86E3 /* Fabric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fabric.h; sourceTree = "<group>"; };
- DA8848891CBB037E00AB86E3 /* SMCalloutView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMCalloutView.h; sourceTree = "<group>"; };
- DA88488A1CBB037E00AB86E3 /* SMCalloutView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SMCalloutView.m; sourceTree = "<group>"; };
DA88488D1CBB047F00AB86E3 /* reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = reachability.h; path = ../../include/mbgl/platform/darwin/reachability.h; sourceTree = "<group>"; };
DA88488F1CBB048E00AB86E3 /* reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = reachability.m; path = src/reachability.m; sourceTree = "<group>"; };
DA8933A01CCC951200E68420 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -734,7 +729,6 @@
DA737EE01D056A4E005BDA16 /* MGLMapViewDelegate.h */,
DA88484A1CBAFB9800AB86E3 /* MGLMapView.mm */,
DA88487F1CBB033F00AB86E3 /* Fabric */,
- DA8848881CBB036000AB86E3 /* SMCalloutView */,
);
name = Kit;
path = src;
@@ -775,16 +769,6 @@
path = ../vendor/Fabric;
sourceTree = "<group>";
};
- DA8848881CBB036000AB86E3 /* SMCalloutView */ = {
- isa = PBXGroup;
- children = (
- DA8848891CBB037E00AB86E3 /* SMCalloutView.h */,
- DA88488A1CBB037E00AB86E3 /* SMCalloutView.m */,
- );
- name = SMCalloutView;
- path = ../vendor/SMCalloutView;
- sourceTree = "<group>";
- };
DA8848911CBB049300AB86E3 /* reachability */ = {
isa = PBXGroup;
children = (
@@ -1006,7 +990,6 @@
DA35A29E1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */,
DA8847F71CBAFA5100AB86E3 /* MGLOverlay.h in Headers */,
DA35A2B11CCA141D00E826B2 /* MGLCompassDirectionFormatter.h in Headers */,
- DA88488B1CBB037E00AB86E3 /* SMCalloutView.h in Headers */,
DA8847FE1CBAFA5100AB86E3 /* MGLTypes.h in Headers */,
DA8847F11CBAFA5100AB86E3 /* MGLGeometry.h in Headers */,
DA8848221CBAFA6200AB86E3 /* MGLOfflineRegion_Private.h in Headers */,
@@ -1396,7 +1379,6 @@
DA8848251CBAFA6200AB86E3 /* MGLPointAnnotation.m in Sources */,
DA88482D1CBAFA6200AB86E3 /* NSBundle+MGLAdditions.m in Sources */,
DA88485B1CBAFB9800AB86E3 /* MGLUserLocation.m in Sources */,
- DA88488C1CBB037E00AB86E3 /* SMCalloutView.m in Sources */,
DA35A2B81CCA9A5D00E826B2 /* MGLClockDirectionFormatter.m in Sources */,
DAD1657A1CF4CDFF001FF4B9 /* MGLShapeCollection.m in Sources */,
DA8848901CBB048E00AB86E3 /* reachability.m in Sources */,
@@ -1438,7 +1420,6 @@
DAA4E42E1CBB730400178DFB /* MGLAPIClient.m in Sources */,
DAA4E4201CBB730400178DFB /* MGLOfflinePack.mm in Sources */,
DAA4E4331CBB730400178DFB /* MGLUserLocation.m in Sources */,
- DAA4E4351CBB730400178DFB /* SMCalloutView.m in Sources */,
DA35A2B91CCA9A5D00E826B2 /* MGLClockDirectionFormatter.m in Sources */,
DAD1657B1CF4CDFF001FF4B9 /* MGLShapeCollection.m in Sources */,
DAA4E4251CBB730400178DFB /* MGLShape.m in Sources */,
diff --git a/platform/ios/src/MGLCalloutView.h b/platform/ios/src/MGLCalloutView.h
index 27d173b230..e0c7bf6352 100644
--- a/platform/ios/src/MGLCalloutView.h
+++ b/platform/ios/src/MGLCalloutView.h
@@ -1,4 +1,5 @@
#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
#import "MGLTypes.h"
diff --git a/platform/ios/src/MGLCompactCalloutView.h b/platform/ios/src/MGLCompactCalloutView.h
index 56c48a99e5..8c0b5b6eca 100644
--- a/platform/ios/src/MGLCompactCalloutView.h
+++ b/platform/ios/src/MGLCompactCalloutView.h
@@ -1,14 +1,10 @@
-#import "SMCalloutView.h"
#import "MGLCalloutView.h"
/**
- A concrete implementation of `MGLCalloutView` based on
- <a href="https://github.com/nfarina/calloutview">SMCalloutView</a>. This
- callout view displays the represented annotation’s title, subtitle, and
- accessory views in a compact, two-line layout.
+ This callout view displays the represented annotation’s title, subtitle, and accessory views in a compact, two-line layout.
*/
-@interface MGLCompactCalloutView : SMCalloutView <MGLCalloutView>
+@interface MGLCompactCalloutView : UIView <MGLCalloutView>
-+ (instancetype)platformCalloutView;
++ (instancetype)calloutView;
@end
diff --git a/platform/ios/src/MGLCompactCalloutView.m b/platform/ios/src/MGLCompactCalloutView.m
index 49812c51a4..2db05cfb76 100644
--- a/platform/ios/src/MGLCompactCalloutView.m
+++ b/platform/ios/src/MGLCompactCalloutView.m
@@ -2,30 +2,165 @@
#import "MGLAnnotation.h"
-@implementation MGLCompactCalloutView
-{
+// Set defaults for custom tip drawing
+static CGFloat const tipHeight = 10.0;
+static CGFloat const tipWidth = 20.0;
+
+@interface MGLCompactCalloutView ()
+
+@property (strong, nonatomic) UIButton *mainBody;
+
+@end
+
+@implementation MGLCompactCalloutView {
id <MGLAnnotation> _representedObject;
+ __unused UIView *_leftAccessoryView;/* unused */
+ __unused UIView *_rightAccessoryView;/* unused */
+ __weak id <MGLCalloutViewDelegate> _delegate;
}
@synthesize representedObject = _representedObject;
+@synthesize leftAccessoryView = _leftAccessoryView;/* unused */
+@synthesize rightAccessoryView = _rightAccessoryView;/* unused */
+@synthesize delegate = _delegate;
-+ (instancetype)platformCalloutView
++ (instancetype)calloutView
{
return [[self alloc] init];
}
-- (void)setRepresentedObject:(id <MGLAnnotation>)representedObject
+- (instancetype)initWithFrame:(CGRect)frame
+{
+ self = [super initWithFrame:frame];
+ if (self)
+ {
+ self.backgroundColor = [UIColor clearColor];
+
+ // Create and add a subview to hold the callout’s text
+ UIButton *mainBody = [UIButton buttonWithType:UIButtonTypeSystem];
+ mainBody.backgroundColor = [self backgroundColorForCallout];
+ mainBody.tintColor = [UIColor whiteColor];
+ mainBody.contentEdgeInsets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
+ mainBody.layer.cornerRadius = 4.0;
+ self.mainBody = mainBody;
+
+ [self addSubview:self.mainBody];
+ }
+
+ return self;
+}
+
+#pragma mark - MGLCalloutView API
+
+- (void)presentCalloutFromRect:(CGRect)rect inView:(UIView *)view constrainedToView:(UIView *)constrainedView animated:(BOOL)animated
+{
+ // Do not show a callout if there is no title set for the annotation
+ if (![self.representedObject respondsToSelector:@selector(title)])
+ {
+ return;
+ }
+
+ [view addSubview:self];
+
+ // Prepare title label
+ [self.mainBody setTitle:self.representedObject.title forState:UIControlStateNormal];
+ [self.mainBody sizeToFit];
+
+ if ([self isCalloutTappable])
+ {
+ // Handle taps and eventually try to send them to the delegate (usually the map view)
+ [self.mainBody addTarget:self action:@selector(calloutTapped) forControlEvents:UIControlEventTouchUpInside];
+ }
+ else
+ {
+ // Disable tapping and highlighting
+ self.mainBody.userInteractionEnabled = NO;
+ }
+
+ // Prepare our frame, adding extra space at the bottom for the tip
+ CGFloat frameWidth = self.mainBody.bounds.size.width;
+ CGFloat frameHeight = self.mainBody.bounds.size.height + tipHeight;
+ CGFloat frameOriginX = rect.origin.x + (rect.size.width/2.0) - (frameWidth/2.0);
+ CGFloat frameOriginY = rect.origin.y - frameHeight;
+ self.frame = CGRectMake(frameOriginX, frameOriginY,
+ frameWidth, frameHeight);
+
+ if (animated)
+ {
+ self.alpha = 0.0;
+
+ [UIView animateWithDuration:0.2 animations:^{
+ self.alpha = 1.0;
+ }];
+ }
+}
+
+- (void)dismissCalloutAnimated:(BOOL)animated
{
- _representedObject = representedObject;
-
- if ([representedObject respondsToSelector:@selector(title)])
+ if (self.superview)
{
- self.title = representedObject.title;
+ if (animated)
+ {
+ [UIView animateWithDuration:0.2 animations:^{
+ self.alpha = 0.0;
+ } completion:^(BOOL finished) {
+ [self removeFromSuperview];
+ }];
+ }
+ else
+ {
+ [self removeFromSuperview];
+ }
}
- if ([representedObject respondsToSelector:@selector(subtitle)])
+}
+
+#pragma mark - Callout interaction handlers
+
+- (BOOL)isCalloutTappable
+{
+ if ([self.delegate respondsToSelector:@selector(calloutViewShouldHighlight:)]) {
+ return [self.delegate performSelector:@selector(calloutViewShouldHighlight:) withObject:self];
+ }
+
+ return NO;
+}
+
+- (void)calloutTapped
+{
+ if ([self isCalloutTappable] && [self.delegate respondsToSelector:@selector(calloutViewTapped:)])
{
- self.subtitle = representedObject.subtitle;
+ [self.delegate performSelector:@selector(calloutViewTapped:) withObject:self];
}
}
+#pragma mark - Custom view styling
+
+- (UIColor *)backgroundColorForCallout
+{
+ return [UIColor darkGrayColor];
+}
+
+- (void)drawRect:(CGRect)rect
+{
+ // Draw the pointed tip at the bottom
+ UIColor *fillColor = [self backgroundColorForCallout];
+
+ CGFloat tipLeft = rect.origin.x + (rect.size.width / 2.0) - (tipWidth / 2.0);
+ CGPoint tipBottom = CGPointMake(rect.origin.x + (rect.size.width / 2.0), rect.origin.y + rect.size.height);
+ CGFloat heightWithoutTip = rect.size.height - tipHeight;
+
+ CGContextRef currentContext = UIGraphicsGetCurrentContext();
+
+ CGMutablePathRef tipPath = CGPathCreateMutable();
+ CGPathMoveToPoint(tipPath, NULL, tipLeft, heightWithoutTip);
+ CGPathAddLineToPoint(tipPath, NULL, tipBottom.x, tipBottom.y);
+ CGPathAddLineToPoint(tipPath, NULL, tipLeft + tipWidth, heightWithoutTip);
+ CGPathCloseSubpath(tipPath);
+
+ [fillColor setFill];
+ CGContextAddPath(currentContext, tipPath);
+ CGContextFillPath(currentContext);
+ CGPathRelease(tipPath);
+}
+
@end
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 60ba726e4f..0a8a467527 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -210,7 +210,6 @@ public:
GLKViewDelegate,
CLLocationManagerDelegate,
UIActionSheetDelegate,
- SMCalloutViewDelegate,
MGLCalloutViewDelegate,
UIAlertViewDelegate,
MGLMultiPointDelegate,
@@ -1586,7 +1585,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
return [self.delegate respondsToSelector:@selector(mapView:tapOnCalloutForAnnotation:)];
}
-- (void)calloutViewClicked:(__unused SMCalloutView *)calloutView
+- (void)calloutViewClicked:(__unused UIView<MGLCalloutView> *)calloutView
{
if ([self.delegate respondsToSelector:@selector(mapView:tapOnCalloutForAnnotation:)])
{
@@ -3528,7 +3527,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
- (MGLCompactCalloutView *)calloutViewForAnnotation:(id <MGLAnnotation>)annotation
{
- MGLCompactCalloutView *calloutView = [MGLCompactCalloutView platformCalloutView];
+ MGLCompactCalloutView *calloutView = [MGLCompactCalloutView calloutView];
calloutView.representedObject = annotation;
calloutView.tintColor = self.tintColor;
diff --git a/platform/ios/vendor/SMCalloutView b/platform/ios/vendor/SMCalloutView
deleted file mode 160000
-Subproject 2aede5d8d1577101bf18405246220e7a710df60