Swift Google Map Marker Tap event does not work for me

0

I am working on Swift Google Maps. I cannot get the didTapMarker delegate to execute when the user taps on the marker. I put the mapView.delegate = self in the viewDidLoad method, but it did not help.

import UIKit
import GoogleMaps
import Alamofire
import ObjectMapper
import SwiftyJSON

class ViewController: UIViewController, GMSMapViewDelegate, GMUClusterManagerDelegate, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
lazy var mapView = GMSMapView()

private var clusterManager: GMUClusterManager!

//true - marker clustering / false - map markers without clustering
let isClustering : Bool = false

//true - images / false - default icons
let isCustom : Bool = false

var userLocation: CLLocation = CLLocation(latitude: 0, longitude: 0)
override func viewDidLoad() {
    super.viewDidLoad()
    // User Location
    locationManager.delegate = self
    locationManager.requestWhenInUseAuthorization()
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.distanceFilter = 10
    locationManager.startUpdatingLocation()
    mapView.delegate = self

}


func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    userLocation = locations.last!

    print("userLocation latitude \(self.userLocation.coordinate.latitude)")
    print("userLocation longitude \(self.userLocation.coordinate.longitude)")

    let camera = GMSCameraPosition.camera(withLatitude: userLocation.coordinate.latitude,
                                          longitude: userLocation.coordinate.longitude, zoom: 17.0)
    mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
    mapView.settings.myLocationButton = true
    mapView.settings.scrollGestures = true
    mapView.settings.zoomGestures = true
    mapView.isMyLocationEnabled = true


    self.view = mapView
    locationManager.stopUpdatingLocation()
    //locationManager.delegate = nil

    fetch()
}

func fetch () {
    let cityLocationService = CityLocationService()
    let cityService = cityLocationService.getCityService(latitude: self.userLocation.coordinate.latitude , longitude: self.userLocation.coordinate.longitude)
    cityService.fetch(latitude: self.userLocation.coordinate.latitude, longitude: self.userLocation.coordinate.longitude) { (incidents) in
        let incidentsJson = incidents
        DispatchQueue.main.async(execute: {
            self.didGetJson(incidentsJson: incidentsJson)
        })
    }

}

func didGetJson(incidentsJson: JSON) {
    if self.isClustering {
        var iconGenerator : GMUDefaultClusterIconGenerator!
        if self.isCustom {
            var images : [UIImage] = []
            for imageID in 1...5 {
                images.append(UIImage(named: "m\(imageID).png")!)
            }
            iconGenerator = GMUDefaultClusterIconGenerator(buckets: [ 10, 50, 100, 200, 500 ], backgroundImages: images)
        } else {
            iconGenerator = GMUDefaultClusterIconGenerator()
        }

        let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
        let renderer = GMUDefaultClusterRenderer(mapView: self.mapView, clusterIconGenerator: iconGenerator)

        self.clusterManager = GMUClusterManager(map: self.mapView, algorithm: algorithm, renderer: renderer)

        self.addToMap(resultJson: incidentsJson, isCluster: true)

        // Call cluster() after items have been added to perform the clustering and rendering on map.
        self.clusterManager.cluster()

        // Register self to listen to both GMUClusterManagerDelegate and GMSMapViewDelegate events.
        self.clusterManager.setDelegate(self, mapDelegate: self)
    } else {
        self.addToMap(resultJson: incidentsJson, isCluster: false)
    }

    self.view = self.mapView
}


func addToMap(resultJson: JSON, isCluster: Bool) {
    for(_, subJson): (String, JSON) in resultJson {
        let position = self.checkIfMutlipleCoordinates(latitude: subJson["latitude"].floatValue, longitude: subJson["longitude"].floatValue)
        let id = subJson["id"]
        let type = subJson["type"].stringValue
        let address = subJson["address"].stringValue
       // let case_number = subJson["case_number"].stringValue
        let date = subJson["date"].stringValue
        let markerImage = subJson["markerImage"].stringValue
        if isCluster {
            let item = POIItem(position: position, name: "#\(id)")
            //  print("pdid name=\(item.name),latitude=\(item.position.latitude),longitude=\(item.position.longitude).")
            clusterManager.add(item)
        } else {
            let marker = GMSMarker(position: position)
            marker.title = "#\(id)"
            let image = UIImage(named: markerImage)
            marker.icon = image?.resized(to: CGSize(width: 30, height: 30))
            marker.opacity = 0.6
            marker.snippet = "\r\n date: \(date) id # \(id) \r\n address: \(address) \r\n type: \(type)"
            marker.map = mapView
        }
    }

}

func checkIfMutlipleCoordinates(latitude : Float , longitude : Float) -> CLLocationCoordinate2D{

    var lat = latitude
    var lng = longitude


    let variation = (self.randomFloat(min: 0.0, max: 2.0) - 0.5) / 1500
    lat = lat + variation
    lng = lng + variation

    let finalPos = CLLocationCoordinate2D(latitude: CLLocationDegrees(lat), longitude: CLLocationDegrees(lng))
    return  finalPos
}

func randomFloat(min: Float, max:Float) -> Float {
    return (Float(arc4random()) / 0xFFFFFFFF) * (max - min) + min
}

func clusterManager(clusterManager: GMUClusterManager, didTapCluster cluster: GMUCluster) {
    let newCamera = GMSCameraPosition.camera(withTarget: cluster.position,
                                             zoom: mapView.camera.zoom + 1)
    let update = GMSCameraUpdate.setCamera(newCamera)
    mapView.moveCamera(update)
}

//Show the marker title while tapping
func mapView(mapView: GMSMapView, didTapMarker marker: GMSMarker) -> Bool {
    print("tapped on marker")

    if marker.title == "myMarker"{
        print("handle specific marker")
    }
    return true
}

//Optional Feature:
//Add new markers while tapping at coordinates without markers/clusters
func mapView(mapView: GMSMapView, didTapAtCoordinate coordinate: CLLocationCoordinate2D) {
    let item = POIItem(position: coordinate, name: "NEW")

    clusterManager.add(item)
    clusterManager.cluster()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

}
ios
swift
google-maps
asked on Stack Overflow Sep 25, 2017 by tim • edited Sep 25, 2017 by voloshin

1 Answer

3

Add delegate GMSMapViewDelegate

mapView.delegate = self // in viewDidLoad

If you want to print lat and long of the touched marker, this is the code:

func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {                
    print("You tapped : \(marker.position.latitude),\(marker.position.longitude)")
    return true // or false as needed.
}

And for long press, if you want to redirect to google maps.

func mapView(_ mapView: GMSMapView, didLongPressInfoWindowOf marker: GMSMarker) {

    if (UIApplication.shared.canOpenURL(NSURL(string:"comgooglemaps://")! as URL)) {

        UIApplication.shared.open(NSURL(string:"comgooglemaps://?saddr=&daddr=\(marker.position.latitude),\(marker.position.longitude)&directionsmode=driving")! as URL, options: [:], completionHandler: nil)
    }
    else {

        let alert = UIAlertController(title: "Google Maps not found", message: "Please install Google Maps in your device.", preferredStyle: UIAlertControllerStyle.alert)

        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))

        self.present(alert, animated: true, completion: nil)
    }
}

This will work!!!

answered on Stack Overflow Sep 25, 2017 by Akhil Nair • edited Jan 8, 2020 by Hemang

User contributions licensed under CC BY-SA 3.0