diff options
author | Jason Wray <jason@mapbox.com> | 2016-05-04 06:25:02 -0400 |
---|---|---|
committer | Jason Wray <jason@mapbox.com> | 2016-07-26 18:28:02 -0700 |
commit | ee85e7d2c2d4639d2bd236dbf3f549f4343b0b27 (patch) | |
tree | 4f2f172bd20051f7de99cc0ded6d451b74c9c404 | |
parent | b3c914fb3f52f6a2b96d663f1c57c97c34eb5e23 (diff) | |
download | qtlocation-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-- | .gitmodules | 4 | ||||
-rw-r--r-- | platform/ios/ios.xcodeproj/project.pbxproj | 19 | ||||
-rw-r--r-- | platform/ios/src/MGLCalloutView.h | 1 | ||||
-rw-r--r-- | platform/ios/src/MGLCompactCalloutView.h | 10 | ||||
-rw-r--r-- | platform/ios/src/MGLCompactCalloutView.m | 155 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 5 | ||||
m--------- | platform/ios/vendor/SMCalloutView | 0 |
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 |