for some odd reason when a marker is tapped google map will not show the snippet window in my swift code. I just dont see what im doing wrong. I get the marker on the map but when i tap it it does not show anything. Thank you in advance.
func viewController(_ viewController: GMSAutocompleteViewController, didAutocompleteWith place: GMSPlace) {
let position = place.coordinate
self.dismiss(animated: true) {
let marker = GMSMarker(position: position)
marker.title = "title here"
marker.snippet = "my snippet here"
marker.map = self.mapView
}
}
I had to remove the delegate below in order for the infowindow to show.
// func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
// print("marker Tapped")
//
// return true
// }
You can put in the delegate
mapView.selectedMarker = marker
so the code will be as this :
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
print("marker Tapped")
mapView.selectedMarker = marker
return true
}
Hope this will help you.
Related
by tapping, it makes marker infinity. i want to one marker where I tapped. over and over again. not with lots markers.
I used MapView.clean(). but it delete every markers.
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D)
{
let marker = GMSMarker(position: coordinate)
marker.position.latitude = coordinate.latitude
marker.position.longitude = coordinate.longitude
print("hello")
print(markerr.position.latitude)
let ULlocation = markerr.position.latitude
let ULlgocation = markerr.position.longitude
print(ULlocation)
print(ULlgocation)
marker.map = self.mapView
}
Create the marker outside the didTapAt coordinate method and change it's coordinates in this method
class ViewController: UIViewController, GMSMapViewDelegate {
let marker = GMSMarker()
override func viewDidLoad() {
super.viewDidLoad()
marker.map = self.mapView
}
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D)
{
marker.position = coordinate
}
}
I'm using google map and I set markers to my map like this:
var marker = GMSMarker(position: CLLocationCoordinate2D(latitude: Double(item.lat)!, longitude: Double(item.lon)!))
marker.map = mapview
now,I would like to detect when user click on these markers.
How can I do?
you should set your mapview delegate to self UIViewController in viewDidLoad
self.mapview.delegate = self
your UIViewController should
extension ViewControllerClass: GMSMapViewDelegate {
//class code
#objc(mapView:didTapMarker:) func mapView(_: GMSMapView, didTap marker: GMSMarker) -> Bool {
//do something
return true
}
}
maybe this method can be implemented some other way already, but Xcode forced me to make it this way while migrating from Swift 2 to Swift 3
For Swift 3
You can implement GMSMapViewDelegatesomething like this:
extension YourViewConytoller: GMSMapViewDelegate {
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
print ("MarkerTapped Locations: \(marker.position.latitude), \(marker.position.longitude)")
return true
}
}
I have a view controller with a GMSMapView and have loaded a number of markers onto the map. I can change which marker is selected with mapView.selectedMarker = ... but how do I change the color of the selected marker?
You can use GMSMarker.markerImage(with: <UIColor?>) to reset a marker's icon.
Docs: Google Maps iOS SDK GMSMarker Class Reference
import GoogleMaps
// view controller
class MapViewController: UIViewController {
// outlets
#IBOutlet weak var mapView: GMSMapView!
// view did load method
override func viewDidLoad() {
super.viewDidLoad()
// set map view delegate
mapView.delegate = self
}
}
// extension for GMSMapViewDelegate
extension MapViewController: GMSMapViewDelegate {
// tap map marker
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
print("didTap marker \(marker.title)")
// remove color from currently selected marker
if let selectedMarker = mapView.selectedMarker {
selectedMarker.icon = GMSMarker.markerImage(with: nil)
}
// select new marker and make green
mapView.selectedMarker = marker
marker.icon = GMSMarker.markerImage(with: UIColor.green)
// tap event handled by delegate
return true
}
}
Simple Way Swift 5
marker.icon = GMSMarker.markerImage(with: UIColor.green)
The accepted answer wasn't working for me because if a user tapped a non-marker on the map, selectedMarker would be set to nil. If the user then tapped another marker, triggering the didTap callback, the selectedMarker would be nil and thus retain its selected state/color.
The fix for me was to remove that selectedMarker logic from didTap and move it to didCloseWindowOf.
Here's the code:
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
marker.icon = UIImage(named: "map_marker_selected")
return false // return false to display info window
}
func mapView(_ mapView: GMSMapView, didCloseInfoWindowOf marker: GMSMarker) {
marker.icon = UIImage(named: "map_marker_unselected")
}
This works because when the user taps a non-marker, the info window closes which triggers didCloseInfoWindowOf.
If you use RxSwift, here is an elegant solution with RxGoogleMaps
Observable.combineLatest(mapView.rx.selectedMarker,
mapView.rx.selectedMarker.skip(1))
.subscribe(onNext: { (old, new) in
old?.icon = GMSMarker.markerImage(with: nil)
new?.icon = GMSMarker.markerImage(with: UIColor.red)
})
.disposed(by: disposeBag)
I know it is possible to capture the taps in the infowindow of a marker. I followed the documentation here.
All are written in Objective C so I tried converting it to Swift, here is my code:
func mapView(_ mapView: GMSMapView, didTap InfoWindowOfMarker: GMSMarker) {
print("You tapped infowindow")
}
But this isn't getting fired at all. What is wrong with the method?
You need to use the delegate of GMSMapView along with some prior setting see below.
Declare the use of GMSMapViewDelegate methods and set the delegate to self:
class yourClassName: UIViewController,GMSMapViewDelegate
mapView?.delegate = self
Method to detect tap on infoWindow:
func mapView(_ mapView: GMSMapView, didTapInfoWindowOf marker: GMSMarker) {
print("infowindow tapped")
}
Method to detect tap on GMSMarker:
func mapView(mapView: GMSMapView, didTapMarker marker: GMSMarker) -> Bool {
print("tapped on marker")
if marker.title == "myMarker"{
print("handle specific marker")
}
return true
}
Method to create custom infoWindow:
func mapView(mapView: GMSMapView!, markerInfoWindow marker: GMSMarker!) -> UIView! {
let infoWindow = Bundle.main.loadNibNamed("nibName", owner: self, options: nil).first as! ClassName
infoWindow.name.text = "title"
infoWindow.address.text = "relevant address"
infoWindow.photo.image = UIImage(named: "imageName")
return infoWindow
}
I want to show a VC as a pop up when the user taps on one of the markers on the Google Map.
The reason that I want to do this is because I want to control the view that pops up when the marker is tapped. I tried using the mapView(mapView: GMSMapView, markerInfoWindow marker: GMSMarker) delegate method. But I don't know how to create a view controller in that method that controls the marker info window's view.
To present a VC as a pop over, I did this:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("MarkerInfoController")
vc.modalInPopover = true
vc.modalPresentationStyle = .Popover
print(marker.iconView)
vc.popoverPresentationController!.sourceView = marker.iconView
self.presentVC(vc) // this is from EZSwiftExtensions. Don't worry about it
The problem arises when I try to set the sourceView of the UIPopoverPresentationController. I thought using the iconView property would work, but no. There is always an error saying that sourceView is not set.
How can I get the UIView instance for the marker, so that I can assign it to sourceView?
P.S. This is how a marker is created:
func mapView(mapView: GMSMapView, didLongPressAtCoordinate coordinate: CLLocationCoordinate2D) {
let marker = GMSMarker(position: coordinate)
marker.map = mapView
}
Output:
Code:
import UIKit
import GoogleMaps
class MapViewController: UIViewController {
#IBOutlet weak var mapView: GMSMapView!
var sourceView: UIView?
}
extension MapViewController: GMSMapViewDelegate {
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
mapCenterPinImage.fadeOut(0.25)
// Adding a delay becuase when click on marker Camera changes it position
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
let location = marker.accessibilityActivationPoint
self.sourceView = UIView(frame: CGRect(x: location.x, y: location.y, width: 1, height: 1))
self.view.addSubview(self.sourceView!)
let popController = MyPopUpViewController()
popController.modalPresentationStyle = UIModalPresentationStyle.popover
popController.preferredContentSize = CGSize(width: 200, height: 200)
popController.popoverPresentationController?.delegate = self
popController.popoverPresentationController?.sourceView = self.sourceView
self.present(popController, animated: true)
}
return false
}
}
extension MapViewController: UIPopoverPresentationControllerDelegate{
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
func popoverPresentationControllerShouldDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) -> Bool {
sourceView?.removeFromSuperview()
sourceView = nil
return true
}
}
What I've done basically created a UIView and added it to ViewController at runtime and set this as a source of Popup and make it nil when it's dismissed.
marker.accessibilityActivationPoint is the source of X and Y according to device's screen
You can just customise the infoView of the GMS Marker instead of showing a viewControlle and perform your desired operations there. You can have a look at this article over here. I faced something similar to your issue and this helped me out. Hope it helps you out as well. :D
https://medium.com/#matschmidy/how-to-implement-custom-and-dynamic-map-marker-info-windows-for-google-maps-ios-e9d993ef46d4
You can do this on below is a gmsMapView delegate mehtod
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool
here you will get the marker which you tapped , and for source view you can access
marker.iconView
which I think will solve your problem, hope it helps :)