Swift 4
Disable the default Google Map current location marker (it's disabled by default):
mapView.isMyLocationEnabled = false
Create a marker as an instance property of the view controller (because a delegate will need access to this):
let currentLocationMarker = GMSMarker()
The GMSMarker
initializer allows for a UIImage
or a UIView
as a custom graphic, not a UIImageView
unfortunately. If you want more control over the graphic, use a UIView
. In your loadView
or viewDidLoad
(wherever you configured the map), configure the marker and add it to the map:
// configure custom view
let currentLocationMarkerView = UIView()
currentLocationMarkerView.frame.size = CGSize(width: 40, height: 40)
currentLocationMarkerView.layer.cornerRadius = 40 / 4
currentLocationMarkerView.clipsToBounds = true
let currentLocationMarkerImageView = UIImageView(frame: currentLocationMarkerView.bounds)
currentLocationMarkerImageView.contentMode = .scaleAspectFill
currentLocationMarkerImageView.image = UIImage(named: "masterAvatar")
currentLocationMarkerView.addSubview(currentLocationMarkerImageView)
// add custom view to marker
currentLocationMarker.iconView = currentLocationMarkerView
// add marker to map
currentLocationMarker.map = mapView
All that remains is giving the marker a coordinate (initially and every time the user's location changes), which you do through the CLLocationManagerDelegate
delegate.
extension MapViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let lastLocation = locations.last!
// update current location marker
currentLocationMarker.position = CLLocationCoordinate2D(latitude: lastLocation.coordinate.latitude, longitude: lastLocation.coordinate.longitude)
}
}
The first few locations that the location manager produces may not be very accurate (although sometimes it is), so expect your custom marker to jump around a bit at first. You can wait until the location manager has gathered a few coordinates before applying it to your custom marker by waiting until locations.count > someNumber
but I don't find this approach very attractive.