问题
So I have been using Google Maps iOS SDK 4.0.0 and my requirement is like this when I tap on a marker it should add UIViewContoller's view which I easily achieved. Take a look on the following code:
var customeVC:CustomViewController?
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
customeVC = CustomViewController(nibName: "CustomViewController", bundle: nil)
customeVC?.delegate = self
self.addChild(customeVC!)
customeVC?.view.frame = self.view.frame
self.view.addSubview(customeVC!.view)
customeVC?.didMove(toParent: self)
// Remember to return false
// so marker event is still handled by delegate
return false
}
func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
//Empty the default infowindow
return UIView()
}
extension MapViewController: CustomViewControllerDelegate {
// Triggers when I close the full screen view of CustomViewController
func didCloseWindow() {
customeVC?.willMove(toParent: nil)
customeVC?.removeFromParent()
customeVC?.view.removeFromSuperview()
customeVC = nil
}
}
Now the main the problem is, after closing the window/view if I click on the same marker again (2nd time) its doesn't show the view. But if I click once again (3rd time), it shows.
So I'm suspecting after removing the view the marker doesn't get deselected. But when I tap for the 2nd time its gets deselected and tap for the 3rd time get selected again.
I have textfields & buttons inside CustomViewController thats why I didn't add this view inside the delegate function mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView?
. Basically I followed this article which lets you click inside InfoWindow.
I also tried to mapView.selectedMarker = marker
inside didTap
delegate method and mapView.selectedMarker = nil
when removing the view.
How do I deselect the marker so that each time I click on the same marker its should show the view?
Any help will be appreciated. Thanks in advance.
回答1:
After trying for several days finally I solved it. Basically tapping on marker works every time only if you draw only markers. But if you draw markers inside an overlay or a polygon then tapping on same marker for the 2nd time didn't work because 2nd time the following method of GMSMapViewDelegate
gets fired.
func mapView(_ mapView: GMSMapView, didTap overlay: GMSOverlay)
I didn't mention that, I was drawing markers inside an overlay because I never thought it can cause tapping issue. I found someone else also faced the issue earlier but his question was unanswered. So here is what I needed to update inside that delegate method to make it work and the rest code are the same.
I'm setting the isTappable
polygon property to false
when I'm tapping on a certain polygon and then I can play around with the markers which are drawn inside.
Also I'm resetting the isTappable
property to true
of previously selected polygon as soon as user clicks on other polygon.
class ViewController: GMSMapViewDelegate {
@IBOutlet weak var mapView:GMSMapView!
private var selectedPolygon: GMSAptivePolygon?
func mapView(_ mapView: GMSMapView, didTap overlay: GMSOverlay) {
if let polygon = overlay as? GMSPolygon {
// Make sure to restrict markers for a polygon if tapped more than once
if selectedPolygon != polygon {
// Reset polygon to tappable
selectedPolygon?.isTappable = true
// Fetch all annotations of this polygon if exits
fetchMarkers(for: polygon)
polygon.isTappable = false
selectedPolygon = polygon
}
}
}
}
回答2:
I suspect your problem is more to do with how you are presenting and dismissing your CustomViewController
because the didTap
delegate method should be called regardless of state.
Initially I would add a test to check if tapping the marker is in-fact triggering the delegate method each time and move some of your presentation code in to a neater method outside of this delegate method e.g.
func showCustomView() {
// make sure any previous CustomViewController are removed
if let vc = self.customeVC {
vc.willMove(toParent: nil)
vc.removeFromParent()
vc.view.removeFromSuperview()
self.customeVC = nil
}
// initialise a new CustomViewController
let cv = CustomViewController(
nibName: "CustomViewController",
bundle: nil
)
cv.delegate = self
self.addChild(cv)
cv.view.frame = self.view.frame
self.view.addSubview(cv.view)
cv.didMove(toParent: self)
self.customeVC = cv
}
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
// print to check the marker is being tapped
print("marker was tapped")
// run presentation code
showCustomView()
// return true to prevent the map from
// performing its default selection behaviour
return true
}
I haven't tested this but I hope it helps you clear up the issue, let me know how you get on.
Another thing I would look in to is presenting the CustomViewController
modally instead making use of modalPresentationStyle
to show the custom view on top of the others without the need to add it as a subview as you are currently.
You'd need something like this in your CustomerViewController
s init
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.modalPresentationStyle = .overCurrentContext
self.modalTransitionStyle = .crossDissolve
self.modalPresentationCapturesStatusBarAppearance = true
}
Then you'd change your showCustomView()
method to something like this
func showCustomView() {
// make sure any previous CustomViewController are removed
if let vc = self.customeVC {
vc.dismiss(animated: true)
self.customeVC = nil
}
// initialise a new CustomViewController
let cv = CustomViewController(
nibName: "CustomViewController",
bundle: nil
)
cv.delegate = self
self.present(cv, animated: true, completion: nil)
self.customeVC = cv
}
This would also assume that you have to dismiss the CustomViewController
before you can interact with any other part of the map, a screenshot of what you are trying to achieve here might help anyone else to help you.
来源:https://stackoverflow.com/questions/65123628/how-to-deselect-a-gmsmarker-after-removing-custom-infowindow-in-google-maps-swif