I manage to find "clean" solution, even though it's still confusing. But it works!
1) Create .h file "MarkerManager"
#import <Foundation/Foundation.h>
@import CoreLocation;
#import "GMUClusterItem.h"
#import <GoogleMaps/GoogleMaps.h>
@interface MarkerManager: NSObject
@property (nonatomic) CLLocationCoordinate2D location;
@property (nonatomic, strong) GMSMarker *marker;
@end
2) Go to GMUDefaultClusterRenderer class in Google-Maps-iOS-Utils folder, import MarkerManager.h class find and change this method:
// Returns a marker at final position of |position| with attached |userData|.
// If animated is YES, animates from the closest point from |points|.
- (GMSMarker *)markerWithPosition:(CLLocationCoordinate2D)position
from:(CLLocationCoordinate2D)from
userData:(id)userData
clusterIcon:(UIImage *)clusterIcon
animated:(BOOL)animated {
GMSMarker *marker = [self markerForObject:userData];
CLLocationCoordinate2D initialPosition = animated ? from : position;
marker.position = initialPosition;
marker.userData = userData;
if (clusterIcon != nil) {
marker.icon = clusterIcon;
marker.groundAnchor = CGPointMake(0.5, 0.5);
}
//added
else {
MarkerManager *data = userData;
if(data != nil) {
marker.icon = data.marker.icon;
}
}
//ends here
marker.zIndex = _zIndex;
if ([_delegate respondsToSelector:@selector(renderer:willRenderMarker:)]) {
[_delegate renderer:self willRenderMarker:marker];
}
marker.map = _mapView;
if (animated) {
[CATransaction begin];
[CATransaction setAnimationDuration:kGMUAnimationDuration];
marker.layer.latitude = position.latitude;
marker.layer.longitude = position.longitude;
[CATransaction commit];
}
if ([_delegate respondsToSelector:@selector(renderer:didRenderMarker:)]) {
[_delegate renderer:self didRenderMarker:marker];
}
return marker;
}
3) Create new swift class, POIItem:
class POIItem: NSObject, GMUClusterItem {
var position: CLLocationCoordinate2D
@objc var marker: GMSMarker!
init(position: CLLocationCoordinate2D, marker: GMSMarker) {
self.position = position
self.marker = marker
}
}
4) Extend GMUDefaultClusterRenderer class and override markerWithPosition method:
import Foundation
import UIKit
class CustomMarkers: GMUDefaultClusterRenderer {
var mapView:GMSMapView?
let kGMUAnimationDuration: Double = 0.5
override init(mapView: GMSMapView, clusterIconGenerator iconGenerator: GMUClusterIconGenerator) {
super.init(mapView: mapView, clusterIconGenerator: iconGenerator)
}
func markerWithPosition(position: CLLocationCoordinate2D, from: CLLocationCoordinate2D, userData: AnyObject, clusterIcon: UIImage, animated: Bool) -> GMSMarker {
let initialPosition = animated ? from : position
let marker = GMSMarker(position: initialPosition)
marker.userData! = userData
if clusterIcon.cgImage != nil {
marker.icon = clusterIcon
}
else {
marker.icon = self.getCustomTitleItem(userData: userData)
}
marker.map = mapView
if animated
{
CATransaction.begin()
CAAnimation.init().duration = kGMUAnimationDuration
marker.layer.latitude = position.latitude
marker.layer.longitude = position.longitude
CATransaction.commit()
}
return marker
}
func getCustomTitleItem(userData: AnyObject) -> UIImage {
let item = userData as! POIItem
return item.marker.icon!
}
}
5) In MapViewController init POIItem in generateClusterItems method:
private func generateClusterItems() {
for object in DataManager.sharedInstance.mapItemsArray {
let doubleLat = Double(object.latitude)
let doubleLong = Double(object.longitude)
let latitude = CLLocationDegrees(doubleLat!)
let longitude = CLLocationDegrees(doubleLong!)
let position = CLLocationCoordinate2DMake(latitude, longitude)
let marker = GMSMarker(position: position)
let item = POIItem(position: position, marker: marker)
self.clusterManager.add(item)
item.mapItem = object
}
}
Inside the for loop you can call:
marker.icon = UIImage(named:"YOUR_IMAGE_NAME")
Now you can set logic to have more then one custom markers.