[ios] basic custom callout view on demo app
This commit is contained in:
committed by
Minh Nguyễn
parent
04ab28b621
commit
b70fd7ae69
16
ios/app/MBXCustomCalloutView.h
Normal file
16
ios/app/MBXCustomCalloutView.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <mbgl/ios/MGLCalloutViewProtocol.h>
|
||||
|
||||
/*
|
||||
* Basic custom callout view to demonstrate how to
|
||||
* add your own on your app. Will only show the
|
||||
* callout title for demonstration purpose.
|
||||
*/
|
||||
|
||||
@interface MBXCustomCalloutView : UIView <MGLCalloutViewProtocol>
|
||||
|
||||
@property (nonatomic, copy) NSString *title, *subtitle;
|
||||
@property (nonatomic, strong) UIView *leftAccessoryView, *rightAccessoryView;
|
||||
@property (nonatomic, weak) id<MGLCalloutViewDelegate> delegate;
|
||||
|
||||
@end
|
||||
82
ios/app/MBXCustomCalloutView.m
Normal file
82
ios/app/MBXCustomCalloutView.m
Normal file
@@ -0,0 +1,82 @@
|
||||
#import "MBXCustomCalloutView.h"
|
||||
|
||||
static CGFloat const tipHeight = 10.0;
|
||||
static CGFloat const tipWidth = 10.0;
|
||||
|
||||
@interface MBXCustomCalloutView ()
|
||||
|
||||
@property (strong, nonatomic) UILabel *mainLabel;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MBXCustomCalloutView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self)
|
||||
{
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
_mainLabel = [[UILabel alloc] initWithFrame: CGRectZero];
|
||||
_mainLabel.backgroundColor = [UIColor clearColor];
|
||||
|
||||
[self addSubview: _mainLabel];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - API
|
||||
|
||||
- (void)presentCalloutFromRect:(CGRect)rect inView:(UIView *)view constrainedToView:(UIView *)constrainedView animated:(BOOL)animated
|
||||
{
|
||||
[view addSubview:self];
|
||||
// prepare title label
|
||||
self.mainLabel.text = self.title;
|
||||
[self.mainLabel sizeToFit];
|
||||
// prepare our frame
|
||||
CGFloat frameWidth = self.mainLabel.bounds.size.width;
|
||||
CGFloat frameHeight = self.mainLabel.bounds.size.height * 2.0;
|
||||
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);
|
||||
}
|
||||
|
||||
- (void)dismissCalloutAnimated:(BOOL)animated
|
||||
{
|
||||
if (self.superview)
|
||||
[self removeFromSuperview];
|
||||
}
|
||||
|
||||
#pragma mark - internals
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
UIColor *fillColor = [UIColor colorWithWhite:0.7 alpha:1.0];
|
||||
|
||||
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;
|
||||
|
||||
// draw the white background with tip
|
||||
CGContextRef ctxt = UIGraphicsGetCurrentContext();
|
||||
|
||||
CGMutablePathRef tipPath = CGPathCreateMutable();
|
||||
CGPathMoveToPoint(tipPath, NULL, 0, 0);
|
||||
CGPathAddLineToPoint(tipPath, NULL, 0, heightWithoutTip);
|
||||
CGPathAddLineToPoint(tipPath, NULL, tipLeft, heightWithoutTip);
|
||||
CGPathAddLineToPoint(tipPath, NULL, tipBottom.x, tipBottom.y);
|
||||
CGPathAddLineToPoint(tipPath, NULL, tipLeft + tipWidth, heightWithoutTip);
|
||||
CGPathAddLineToPoint(tipPath, NULL, CGRectGetWidth(rect), heightWithoutTip);
|
||||
CGPathAddLineToPoint(tipPath, NULL, CGRectGetWidth(rect), 0);
|
||||
CGPathCloseSubpath(tipPath);
|
||||
|
||||
[fillColor setFill];
|
||||
CGContextAddPath(ctxt, tipPath);
|
||||
CGContextFillPath(ctxt);
|
||||
CGPathRelease(tipPath);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -1,4 +1,5 @@
|
||||
#import "MBXViewController.h"
|
||||
#import "MBXCustomCalloutView.h"
|
||||
|
||||
#import <mbgl/ios/Mapbox.h>
|
||||
#import <mbgl/util/default_styles.hpp>
|
||||
@@ -7,6 +8,7 @@
|
||||
#import <OpenGLES/ES2/gl.h>
|
||||
|
||||
static UIColor *const kTintColor = [UIColor colorWithRed:0.120 green:0.550 blue:0.670 alpha:1.000];
|
||||
static NSString * const kCustomCalloutTitle = @"Custom Callout";
|
||||
|
||||
static const CLLocationCoordinate2D WorldTourDestinations[] = {
|
||||
{ 38.9131982, -77.0325453144239 },
|
||||
@@ -151,6 +153,7 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
|
||||
@"Add 10,000 Points",
|
||||
@"Add Test Shapes",
|
||||
@"Start World Tour",
|
||||
@"Add 1 custom Point",
|
||||
@"Remove Annotations",
|
||||
@"Toggle Custom Style Layer",
|
||||
nil];
|
||||
@@ -261,9 +264,13 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
|
||||
}
|
||||
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 9)
|
||||
{
|
||||
[self.mapView removeAnnotations:self.mapView.annotations];
|
||||
[self presentAnnotationWithCustomCallout];
|
||||
}
|
||||
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 10)
|
||||
{
|
||||
[self.mapView removeAnnotations:self.mapView.annotations];
|
||||
}
|
||||
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 11)
|
||||
{
|
||||
if (_isShowingCustomStyleLayer)
|
||||
{
|
||||
@@ -377,6 +384,18 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
|
||||
[self.mapView removeCustomStyleLayerWithIdentifier:@"mbx-custom"];
|
||||
}
|
||||
|
||||
- (void)presentAnnotationWithCustomCallout
|
||||
{
|
||||
[self.mapView removeAnnotations:self.mapView.annotations];
|
||||
|
||||
MGLPointAnnotation *annotation = [MGLPointAnnotation new];
|
||||
annotation.coordinate = CLLocationCoordinate2DMake(48.8533940, 2.3775439);
|
||||
annotation.title = kCustomCalloutTitle;
|
||||
|
||||
[self.mapView addAnnotation:annotation];
|
||||
[self.mapView showAnnotations:@[annotation] animated:YES];
|
||||
}
|
||||
|
||||
- (void)handleLongPress:(UILongPressGestureRecognizer *)longPress
|
||||
{
|
||||
if (longPress.state == UIGestureRecognizerStateBegan)
|
||||
@@ -475,7 +494,11 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
|
||||
|
||||
- (MGLAnnotationImage *)mapView:(MGLMapView * __nonnull)mapView imageForAnnotation:(id <MGLAnnotation> __nonnull)annotation
|
||||
{
|
||||
if ([annotation.title isEqualToString:@"Dropped Marker"]) return nil; // use default marker
|
||||
if ([annotation.title isEqualToString:@"Dropped Marker"]
|
||||
|| [annotation.title isEqualToString:kCustomCalloutTitle])
|
||||
{
|
||||
return nil; // use default marker
|
||||
}
|
||||
|
||||
NSString *title = [(MGLPointAnnotation *)annotation title];
|
||||
if (!title.length) return nil;
|
||||
@@ -576,4 +599,16 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
|
||||
}];
|
||||
}
|
||||
|
||||
- (UIView<MGLCalloutViewProtocol> *)mapView:(__unused MGLMapView *)mapView customCalloutViewForAnnotation:(id<MGLAnnotation>)annotation
|
||||
{
|
||||
if ([annotation respondsToSelector:@selector(title)]
|
||||
&& [annotation.title isEqualToString:kCustomCalloutTitle])
|
||||
{
|
||||
MBXCustomCalloutView *calloutView = [[MBXCustomCalloutView alloc] init];
|
||||
calloutView.title = annotation.title;
|
||||
return calloutView;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
'./main.m',
|
||||
'./MBXAppDelegate.h',
|
||||
'./MBXAppDelegate.m',
|
||||
'./MBXCustomCalloutView.h',
|
||||
'./MBXCustomCalloutView.m',
|
||||
'./MBXViewController.h',
|
||||
'./MBXViewController.mm',
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user