Mapbox - setCenterCoordinate is deselecting annotations - ios

I'm trying out mapbox (using the ios sdk) and I've run into a problem that I think I've narrowed down pretty far. This is my code:
func centerMap(location: CLLocationCoordinate2D) {
map.setCenterCoordinate(location,
zoomLevel: 14,
animated: true)
}
func mapView(mapView: MGLMapView, didDeselectAnnotation annotation: MGLAnnotation) {
dealDetails.hidden = false
}
func mapView(mapView: MGLMapView, didUpdateUserLocation userLocation: MGLUserLocation?) {
if let currentLocation = userLocation?.coordinate {
centerMap(currentLocation)
}
}
If I don't re-center the map when the user's location is updated (i.e., just commenting out the centerMap(currentLocation) call) then the annotation remains selected. Re-centering the map calls the didDeselectAnnotation function, and I can't figure out how to keep that annotation selected. Any help is appreciated!

I don't think there's any way around that if you update the center coordinate. You'd have to re-select the annotation. However, you probably don't need to do that. If you set the userTrackingMode on the map view to .Follow, it should re-center automatically.

Related

How to zoom, in MGL mapView, so that the view encompasses one "object" on the map

I have an MGLPolyline on a mapbox map and want to make is so when the user taps on the line it centers around the line and zooms in as much as possible so that the full line is on display. Currently, I make the centering work well but the zoom works randomly:
I just set it to max zoom, However, this is of course not what I want.
Bellow is where I want to add the zoom amount:
func mapView(_ mapView: MGLMapView, didSelect annotation: MGLAnnotation) {
print("Tapped")
mapView.setCenter(CLLocationCoordinate2D(latitude: annotation.coordinate.latitude, longitude: annotation.coordinate.longitude), zoomLevel: mapView.zoomLevel, animated: true)
mapView.deselectAnnotation(annotation, animated: false)
}
MGLMapView actually has a baked in method specifically for this purpose. You should be able to implement the functionality using -showAnnotations:animated. If you want to fiddle around with the padding around your polyline, you can also use the showAnnotations:edgePadding:animated flavor of the method.
This would look like the following:
func mapView(_ mapView: MGLMapView, didSelect annotation: MGLAnnotation) {
mapView.showAnnotations(pointAnnotations, animated: true)
}

Get lat/long from the google mapview

I need to get the lat/long of the location where user taps on the google map view. Is there a necessity to open GooglePlacePickerViewController for this? I need to achieve this in the GMSMapView which is used to show user current location.
It is simple use Delegate method
First set delegate
self.mapView.delegate = self
Then just
extension YourViewController:GMSMapViewDelegate {
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
// USER TAP ON coordinate
}
}
Suggestion : Just go through this tutorial https://medium.freecodecamp.org/how-you-can-use-the-google-maps-sdk-with-ios-using-swift-4-a9bba26d9c4d will not take more than 20 min that my promise will conver all the basic stuff. :)
If you need points of view based system. for example if you want what is exact point where user tap according to view X, Y
Then
you can do it like this
let points:CGPoint = mapView.projection.point(for:coordinates)
Bingo !!
assign delegate like this.
mapView.delegate = self
And use GMSMapViewDelegate to use below method
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
print("You tapped at Location \(coordinate.latitude), \(coordinate.longitude)")
}

Stopping all animations in place on MKMapView Swift 3 iOS

I have been stuck on this issue for the past day. I have created a custom MKAnnotation subclass to display various custom pins on an MKMapView. I recursively call a function that keeps animating these pins around the map. My goal is to stop all of these animations in place when the user taps on a button. I have tried
self.view.layer.removeAllAnimations()
and
self.map.layer.removeAllAnimations()
and other hacky solutions, but none seem to work.
Below is the code that creates the animation/pin movement
func animate(duration:Double, newLocation:CLLocationCoordinate2D){
UIView.animate(withDuration: duration, animations: {
self.coordinate = newLocation
}) { (done) in
self.finished_segment()
}
}
Any suggestions are much appreciated.
For anyone stuck on this issue. The problem was that I had to remove the animation from the MKAnnotationView associated with the annotation. I basically created a member variable in the custom class that I set in the mapView annotation delegate method as seen below.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "annotationView") ?? MKAnnotationView()
if let a = annotation as? Alien{
annotationView.image = a.image
a.annotationView = annotationView
}
return annotationView
}
And to remove the animation from the map. Simply call
self.annotationView.layer.removeAllAnimations()

How to make a MGLPolyline tapable?

I am currently looking for a way to make a route (MGPLPolyline) tappable such that a user can choose between two possible routes under Mapbox. Unfortunately the route annotation doesn't seem to be tappable at all:
While i have properly set my MGLMapViewDelegate this method:
func mapView(_ mapView: MGLMapView, didSelect annotation: MGLAnnotation)
is never invoked.
What did i miss knowing that each line inherited from MGLPolyline which is a subclass of an MGLAnnotation (which i was expected to be tappable...).
The Mapbox iOS API doesn't support that yet, unfortunately. See here.
There are a couple of workarounds within that link that you could try though.
UPDATE:
This is now possible: Check here.
You could do the following:
First, when you create the polyline do the following:
let polyline = CustomPolyline(coordinates: &coordinates, count: UInt(coordinates.count))
polyline.title = "" //It does not seem to matter what you set it to.
polyline.color = .darkGray
Then in the following method return false:
func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
// Always allow callouts to popup when annotations are tapped.
print("ran?")
return false
}

Custom info window in IOS google maps sdk

being a newby IOS developer, I'm really struggling to get something basic to work.
I have a need to display this kind of custom info window upon a marker click in the google maps sdk for ios.
Any help would be appreciated.
I've already seen the third party components, but even with them I cannot get this to display. There is always a title, snippet, left image and right image part. The real question is how do you get the gold star rating in the window, with the text next to it.
Make Xib as you want...set Text and image
set delegate GMSMapViewDelegate
-(UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker{
CustomInfoWindow *infoWindow=[[[NSBundle mainBundle] loadNibNamed:#"InfoWindow" owner:self options:nil] objectAtIndex:0];
return infoWindow;
}
https://www.youtube.com/watch?v=ILiBXYscsyY
for more help
see this video..Uploded by google
I was suffering from the same problem of Info window customization in GoogleMapsSdk for iOS for a lot of days, got frustrated & did it my self!
Clean, Completely customizable & Own UIControls with your custom actions code can be found on Github Right here
Happy coding :)
Swift 3.0 Solution
Google Map CustomInfoWindow
//empty the default infowindow
func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
return UIView()
}
// reset custom infowindow whenever marker is tapped
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
customInfoView.removeFromSuperview()
// customInfoView.button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
self.view.addSubview(customInfoView)
// Remember to return false
// so marker event is still handled by delegate
return false
}
// let the custom infowindow follows the camera
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
if (locationMarker != nil){
let location = locationMarker.position
customInfoView.center = mapView.projection.point(for: location)
}
}
// take care of the close event
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
customInfoView.removeFromSuperview()
}
ended up using SMCalloutView # https://github.com/nfarina/calloutview

Resources