Markers indicate single locations on the map.
By default, markers use a standard icon that has the common Google Maps look and feel. If you want to customize your marker, you can change the color of the default marker, or replace the marker image with a custom icon, or change other properties of the marker.
Add a marker
To add a marker, create a GMSMarker object that includes a position and
title, and set its map.
The following example demonstrates how to add a marker to an existing
GMSMapView object. The marker is created at coordinates 10,10, and displays
the string "Hello world" in an info window when clicked.
Swift
let position = CLLocationCoordinate2D(latitude: 10, longitude: 10)
let marker = GMSMarker(position: position)
marker.title = "Hello World"
marker.map = mapView
Objective-C
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(10, 10);
GMSMarker *marker = [GMSMarker markerWithPosition:position];
marker.title = @"Hello World";
marker.map = mapView;
You can animate the addition of new markers to the map by setting the
marker.appearAnimation property to kGMSMarkerAnimationPop.
Remove a marker
You can remove a marker from the map by setting the map property of the
GMSMarker to nil. Alternatively, you can remove all of the overlays
(including markers) currently on the map by calling the GMSMapView clear
method.
Swift
let camera = GMSCameraPosition.camera(withLatitude: -33.8683, longitude: 151.2086, zoom: 6)
let mapView = GMSMapView.map(withFrame: .zero, camera: camera)
...
mapView.clear()
Objective-C
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.8683
longitude:151.2086
zoom:6];
mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
...
[mapView clear];
If you wish to make modifications to a marker after you've added it to the map,
ensure that you keep hold of the GMSMarker object. You can modify the marker
later by making changes to this object.
Swift
let marker = GMSMarker(position: position)
marker.map = mapView
...
marker.map = nil
Objective-C
GMSMarker *marker = [GMSMarker markerWithPosition:position];
marker.map = mapView;
...
marker.map = nil
Change the marker color
You can customize the color of the default marker image by requesting a tinted
version of the default icon with markerImageWithColor:, and passing
the resulting image to the GMSMarker's icon property.
Swift
marker.icon = GMSMarker.markerImage(with: .black)
Objective-C
marker.icon = [GMSMarker markerImageWithColor:[UIColor blackColor]];
Customize the marker image
If you want to change the default marker image you can set a custom icon, using
the marker's icon or iconView property.
If iconView is set, the API ignores the icon property. Updates to the
current icon are not recognised as long as the iconView is set.
Use the marker's icon property
The following snippet creates a marker with a custom icon provided as a
UIImage in the icon property. The icon is centered at London, England. The
snippet assumes that your application contains an image named "house.png".
Swift
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let london = GMSMarker(position: position)
london.title = "London"
london.icon = UIImage(named: "house")
london.map = mapView
Objective-C
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127);
GMSMarker *london = [GMSMarker markerWithPosition:position];
london.title = @"London";
london.icon = [UIImage imageNamed:@"house"];
london.map = mapView;
If you are creating several markers with the same image, use the same instance
of UIImage for each of the markers. This helps improve the performance
of your application when displaying many markers.
This image may have multiple frames. Additionally, the alignmentRectInsets
property is respected, which is useful if a marker has a shadow or other
unusable region.
Use the marker's iconView property
The following snippet creates a marker with a custom icon by setting the
marker's iconView property, and animates a change in the color of the marker.
The snippet assumes that your application contains an image named "house.png".
Swift
import UIKit
import GoogleMaps
class ViewController: UIViewController, GMSMapViewDelegate {
var mapView: GMSMapView!
var london: GMSMarker?
var londonView: UIImageView?
override func loadView() {
let camera = GMSCameraPosition.camera(withLatitude: 51.5,
longitude: -0.127,
zoom: 14)
let mapView = GMSMapView.map(withFrame: .zero, camera: camera)
view = mapView
mapView.delegate = self
let house = UIImage(named: "House")!.withRenderingMode(.alwaysTemplate)
let markerView = UIImageView(image: house)
markerView.tintColor = .red
londonView = markerView
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let marker = GMSMarker(position: position)
marker.title = "London"
marker.iconView = markerView
marker.tracksViewChanges = true
marker.map = mapView
london = marker
}
func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
UIView.animate(withDuration: 5.0, animations: { () -> Void in
self.londonView?.tintColor = .blue
}, completion: {(finished) in
// Stop tracking view changes to allow CPU to idle.
self.london?.tracksViewChanges = false
})
}
Objective-C
#import "ViewController.h"
@import GoogleMaps;
@interface ViewController () <GMSMapViewDelegate>
@property (strong, nonatomic) GMSMapView *mapView;
@end
@implementation ViewController {
GMSMarker *_london;
UIImageView *_londonView;
}
- (void)viewDidLoad {
[super viewDidLoad];
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:51.5
longitude:-0.127
zoom:14];
_mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
self.view = _mapView;
_mapView.delegate = self;
UIImage *house = [UIImage imageNamed:@"House"];
house = [house imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
_londonView = [[UIImageView alloc] initWithImage:house];
_londonView.tintColor = [UIColor redColor];
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127);
_london = [GMSMarker markerWithPosition:position];
_london.title = @"London";
_london.iconView = _londonView;
_london.tracksViewChanges = YES;
_london.map = self.mapView;
}
- (void)mapView:(GMSMapView *)mapView
idleAtCameraPosition:(GMSCameraPosition *)position {
[UIView animateWithDuration:5.0
animations:^{
_londonView.tintColor = [UIColor blueColor];
}
completion:^(BOOL finished) {
// Stop tracking view changes to allow CPU to idle.
_london.tracksViewChanges = NO;
}];
}
@end
Because iconView accepts a UIView, you can have a hierarchy of standard UI
controls defining your markers, each view having the standard set of animation
capabilities. You can include changes to the marker size, color, and alpha
levels, as well as applying arbitrary transformations. The iconView property
supports animation of all animatable properties of UIView except frame and
center.
Please note the following considerations when using iconView:
- The
UIViewcan be demanding on resources whentracksViewChangesis set toYES, which may result in increased battery usage. In comparison, a single frameUIImageis static and does not need to be re-rendered. - Some devices may struggle to render the map if you have many markers on
screen, and each marker has its own
UIView, and all markers are tracking changes at the same time. - An
iconViewdoes not respond to user interaction, as it is simply a snapshot of the view. - The view behaves as if
clipsToBoundsis set toYES, regardless of its actual value. You can apply transforms that work outside the bounds, but the object you draw must be within the bounds of the object. All transforms/shifts are monitored and applied. In short: subviews must be contained within the view.
To decide when to set the tracksViewChanges property, you
should weigh up performance considerations against the advantages of having the
marker redrawn automatically. For example:
- If you have a series of changes to make, you can change the property to
YESthen back toNO. - When an animation is running or the contents are being loaded asynchronously,
you should keep the property set to
YESuntil the actions are complete.
Change the marker opacity
You can control the opacity of a marker with its opacity property. You should
specify the opacity as a float between 0.0 and 1.0, where 0 is fully transparent
and 1 is fully opaque.
Swift
marker.opacity = 0.6
Objective-C
marker.opacity = 0.6;
You can animate the marker opacity with Core Animation via the
GMSMarkerLayer.
Flatten a marker
Marker icons are normally drawn oriented against the device's screen rather than the map's surface, so rotating, tilting or zooming the map does not necessarily change the orientation of the marker.
You can set the orientation of a marker to be flat against the earth. Flat markers rotate when the map is rotated, and change perspective when the map is tilted. As with regular markers, flat markers retain their size when the map is zoomed in or out.
To change the orientation of the marker, set the marker's flat property to
YES or true.
Swift
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let london = GMSMarker(position: position)
london.isFlat = true
london.map = mapView
Objective-C
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127);
GMSMarker *london = [GMSMarker markerWithPosition:position];
london.flat = YES;
london.map = mapView;
Rotate a marker
You can rotate a marker around its anchor point by setting the rotation
property. Specify the rotation as a CLLocationDegrees type, measured in
degrees clockwise from the default position. When the marker is flat on the
map, the default position is North.
The following example rotates the marker 90°. Setting the groundAnchor
property to 0.5,0.5 causes the marker to be rotated around its center,
instead of its base.
Swift
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let degrees = 90.0
let london = GMSMarker(position: position)
london.groundAnchor = CGPoint(x: 0.5, y: 0.5)
london.rotation = degrees
london.map = mapView
Objective-C
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127);
CLLocationDegrees degrees = 90;
GMSMarker *london = [GMSMarker markerWithPosition:position];
london.groundAnchor = CGPointMake(0.5, 0.5);
london.rotation = degrees;
london.map = mapView;
Add an info window
Use an info window to display information to the user when they tap on
a marker. Only one info window is displayed at a time. If a user taps on
another marker, the current window is hidden and the new info window opens.
The contents of the info window are defined by the title and
snippet properties. Clicking the marker does not display an info window
if both the title and snippet properties are blank or nil.
The following snippet creates a simple marker, with only a title for the text of the info window.
Swift
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let london = GMSMarker(position: position)
london.title = "London"
london.map = mapView
Objective-C
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127);
GMSMarker *london = [GMSMarker markerWithPosition:position];
london.title = @"London";
london.map = mapView;
With the snippet property, you can add additional text that will appear
below the title in a smaller font. Strings that are longer than the width of
the info window are automatically wrapped over several lines. Very long
messages may be truncated.
Swift
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let london = GMSMarker(position: position)
london.title = "London"
london.snippet = "Population: 8,174,100"
london.map = mapView
Objective-C
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127);
GMSMarker *london = [GMSMarker markerWithPosition:position];
london.title = @"London";
london.snippet = @"Population: 8,174,100";
london.map = mapView;
Set an info window to refresh automatically
Set tracksInfoWindowChanges on the
marker to YES or true if you want new properties or the content of the info
window to be immediately displayed when changed, rather than having to wait for
the info window to hide and then show again. The default is NO or false.
Swift
marker.tracksInfoWindowChanges = true
Objective-C
marker.tracksInfoWindowChanges = YES;
To decide when to set the
tracksInfoWindowChanges property, you
should weigh up performance considerations against the advantages of having the
info window redrawn automatically. For example:
- If you have a series of changes to make, you can change the property to
YESthen back toNO. - When an animation is running or the contents are being loaded asynchronously,
you should keep the property set to
YESuntil the actions are complete.
Refer also to the notes for consideration when
using the iconView property of the marker.
Change the position of an info window
An info window is drawn oriented against the device's screen, centered
above its associated marker. You can alter the position of the info window
relative to the marker by setting the infoWindowAnchor property. This
property accepts a CGPoint, defined as an (x,y) offset where both x and y
range between 0.0 and 1.0. The default offset is (0.5, 0.0), that is, the center
top. Setting the infoWindowAnchor offset is useful for aligning the info
window against a custom icon.
Swift
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let london = GMSMarker(position: position)
london.title = "London"
london.snippet = "Population: 8,174,100"
london.infoWindowAnchor = CGPoint(x: 0.5, y: 0.5)
london.icon = UIImage(named: "house")
london.map = mapView
Objective-C
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127);
GMSMarker *london = [GMSMarker markerWithPosition:position];
london.title = @"London";
london.snippet = @"Population: 8,174,100";
london.infoWindowAnchor = CGPointMake(0.5, 0.5);
london.icon = [UIImage imageNamed:@"house"];
london.map = mapView;
Handle events on markers and info windows
You can listen to events that occur on the map, such as when a user taps a
marker or an info window. To listen to events, you must implement the
GMSMapViewDelegate protocol. See the
guide to events and the list of methods on the
GMSMapViewDelegate. For Street View events, see the
GMSPanoramaViewDelegate.
