Annotation views
A newer version of the Maps SDK is available
This page uses v6.4.1 of the Mapbox Maps SDK. A newer version of the SDK is available. Learn about the latest version, v11.8.0, in the Maps SDK documentation.
This example uses two classes within a single file:
CustomAnnotationView
is a subclass ofMGLAnnotationView
, a descendant ofUIView
.ViewController
uses these annotation views withMGLMapView
.
To learn about more ways to add points to a map, see the Markers and annotations guide.
import Mapbox
// Example view controller
class ViewController: UIViewController, MGLMapViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let mapView = MGLMapView(frame: view.bounds)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.styleURL = MGLStyle.darkStyleURL
mapView.tintColor = .lightGray
mapView.centerCoordinate = CLLocationCoordinate2D(latitude: 0, longitude: 66)
mapView.zoomLevel = 2
mapView.delegate = self
view.addSubview(mapView)
// Specify coordinates for our annotations.
let coordinates = [
CLLocationCoordinate2D(latitude: 0, longitude: 33),
CLLocationCoordinate2D(latitude: 0, longitude: 66),
CLLocationCoordinate2D(latitude: 0, longitude: 99)
]
// Fill an array with point annotations and add it to the map.
var pointAnnotations = [MGLPointAnnotation]()
for coordinate in coordinates {
let point = MGLPointAnnotation()
point.coordinate = coordinate
point.title = "\(coordinate.latitude), \(coordinate.longitude)"
pointAnnotations.append(point)
}
mapView.addAnnotations(pointAnnotations)
}
// MARK: - MGLMapViewDelegate methods
// This delegate method is where you tell the map to load a view for a specific annotation. To load a static MGLAnnotationImage, you would use `-mapView:imageForAnnotation:`.
func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
// This example is only concerned with point annotations.
guard annotation is MGLPointAnnotation else {
return nil
}
// Use the point annotation’s longitude value (as a string) as the reuse identifier for its view.
let reuseIdentifier = "\(annotation.coordinate.longitude)"
// For better performance, always try to reuse existing annotations.
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
// If there’s no reusable annotation view available, initialize a new one.
if annotationView == nil {
annotationView = CustomAnnotationView(reuseIdentifier: reuseIdentifier)
annotationView!.bounds = CGRect(x: 0, y: 0, width: 40, height: 40)
// Set the annotation view’s background color to a value determined by its longitude.
let hue = CGFloat(annotation.coordinate.longitude) / 100
annotationView!.backgroundColor = UIColor(hue: hue, saturation: 0.5, brightness: 1, alpha: 1)
}
return annotationView
}
func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
return true
}
}
//
// MGLAnnotationView subclass
class CustomAnnotationView: MGLAnnotationView {
override func layoutSubviews() {
super.layoutSubviews()
// Use CALayer’s corner radius to turn this view into a circle.
layer.cornerRadius = bounds.width / 2
layer.borderWidth = 2
layer.borderColor = UIColor.white.cgColor
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Animate the border width in/out, creating an iris effect.
let animation = CABasicAnimation(keyPath: "borderWidth")
animation.duration = 0.1
layer.borderWidth = selected ? bounds.width / 4 : 2
layer.add(animation, forKey: "borderWidth")
}
}
#import "ViewController.h"
@import Mapbox;
// MGLAnnotationView subclass
@interface CustomAnnotationView : MGLAnnotationView
@end
@implementation CustomAnnotationView
- (void)layoutSubviews {
[super layoutSubviews];
// Use CALayer’s corner radius to turn this view into a circle.
self.layer.cornerRadius = self.bounds.size.width / 2;
self.layer.borderWidth = 2;
self.layer.borderColor = [UIColor whiteColor].CGColor;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Animate the border width in/out, creating an iris effect.
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"borderWidth"];
animation.duration = 0.1;
self.layer.borderWidth = selected ? self.bounds.size.width / 4 : 2;
[self.layer addAnimation:animation forKey:@"borderWidth"];
}
@end
//
// Example view controller
@interface ViewController () <MGLMapViewDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
mapView.styleURL = [MGLStyle darkStyleURL];
mapView.tintColor = [UIColor lightGrayColor];
mapView.centerCoordinate = CLLocationCoordinate2DMake(0, 66);
mapView.zoomLevel = 2;
mapView.delegate = self;
[self.view addSubview:mapView];
// Specify coordinates for our annotations.
CLLocationCoordinate2D coordinates[] = {
CLLocationCoordinate2DMake(0, 33),
CLLocationCoordinate2DMake(0, 66),
CLLocationCoordinate2DMake(0, 99),
};
NSUInteger numberOfCoordinates = sizeof(coordinates) / sizeof(CLLocationCoordinate2D);
// Fill an array with point annotations and add it to the map.
NSMutableArray *pointAnnotations = [NSMutableArray arrayWithCapacity:numberOfCoordinates];
for (NSUInteger i = 0; i < numberOfCoordinates; i++) {
CLLocationCoordinate2D coordinate = coordinates[i];
MGLPointAnnotation *point = [[MGLPointAnnotation alloc] init];
point.coordinate = coordinate;
point.title = [NSString stringWithFormat:@"%.f, %.f", coordinate.latitude, coordinate.longitude];
[pointAnnotations addObject:point];
}
[mapView addAnnotations:pointAnnotations];
}
#pragma mark - MGLMapViewDelegate methods
// This delegate method is where you tell the map to load a view for a specific annotation. To load a static MGLAnnotationImage, you would use `-mapView:imageForAnnotation:`.
- (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id <MGLAnnotation>)annotation {
// This example is only concerned with point annotations.
if (![annotation isKindOfClass:[MGLPointAnnotation class]]) {
return nil;
}
// Use the point annotation’s longitude value (as a string) as the reuse identifier for its view.
NSString *reuseIdentifier = [NSString stringWithFormat:@"%f", annotation.coordinate.longitude];
// For better performance, always try to reuse existing annotations.
CustomAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier];
// If there’s no reusable annotation view available, initialize a new one.
if (!annotationView) {
annotationView = [[CustomAnnotationView alloc] initWithReuseIdentifier:reuseIdentifier];
annotationView.bounds = CGRectMake(0, 0, 40, 40);
// Set the annotation view’s background color to a value determined by its longitude.
CGFloat hue = (CGFloat)annotation.coordinate.longitude / 100;
annotationView.backgroundColor = [UIColor colorWithHue:hue saturation:0.5 brightness:1 alpha:1];
}
return annotationView;
}
- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id<MGLAnnotation>)annotation {
return YES;
}
@end