I have implemented a CLLocationManager to show user location. Once a user clicks a button, the map zooms in the user location. However, once the user would like to zoom out back, it does not allow user to zoom out. Actually, it zooms out a little bit, but again it zooms in!!
You do not need to use CLLocationManager to get the user location when you have a map view. You can use the map view's userLocation property, and you can also listen to the delegate callback that will give you updates about the user location.
Since you are not presenting any code, I would say that either on the MKMapView delegate method or the CLLocationManager delegate method, you are zooming in and/or focusing on the newest location. Since this is a delegate method being updated as soon as there is a new location, you might be zooming in every time. If you only want to zoom in once, you might want to try dispatching a dispatch_once block to make sure that you are only zooming in the first time there is a coordinate update. You can also modify the CLLocationManager so it only updates the location when there has been a significant distance change by using the distance filter property. It all depends on what you are trying to accomplish.
Related
I'm designing an app using Swift for a food truck. I want to use MapKit to show a pin on the live location of the truck so one can look at the app to see it moving in realtime. I was able to get the server-side element set up using PHP/MySQL. Currently, the app makes a HTTP request every 3 seconds.
How should I go about animating the moving pin (or other image)? I tried a few methods already (if you have others, please suggest!):
I removed the pin and quickly added a new one in my HTTP function. While this works, I would prefer a smooth animation, not a flashing, jerky pin.
I subclassed MKMapViewDelgate like with a didAddAnnotationViews delegate that animates the pin's frame using UIView.animateWithDuration as suggested here. Animation only occurred when the map was initially loaded. Also, I have no idea how this would work with coordinates, since it involves frames.
I subclassed MKAnnotation with a modifiable var coordinate. In my HTTP function, I changed the coordinate. EDIT: This now works since I properly refreshed the mapView (thanks #Paulw11). However, I still have two main issues:
There's no linear animation, which I desire to better simulate real-time movement. How would I go about animating the pin's coordinates? Should I use UIView, like in method 2, a fast NSTimer, or something else?
Due to using the setCenterCoordinate function to forcibly refresh the map, the map cancels any current touches. How do I detect if there's any touches on the MapView so I can prevent the forced update?
Ok so I have a map loaded with pins from a remote JSON feed which is loaded into the app. This all works fine.
Now from initial experimenting regionDidChangeAnimated gets called multiple times and so I moved my post request to a method that uses a drag map gesture recogniser which then performs a post request to get data from a JSON feed and reload my map pins after removing them. This also works perfectly.
Now the only issue I have left is if I select an annotation that is close to the edge of the screen the map moves slightly to accommodate the display of the annotation callout. The problem is regionDidChangeAnimated gets called when this happens however my post request doesn't as I call it using the gesture recogniser and so the map was not moved by user intervention but the OS. I don't want to move my Post request to the regionDidChangeAnimated as this gets called multiple times but I would like to know if there is a way to do a test if user caused map to move or it did it its-self to accommodate the callout as explained above. The regionDidChangeAnimated from the research I have looked at may get called more times than necessary so some guidance would be good on how to prevent that or detect user interaction vs OS moving the map.
I have a similar problem: I want do distinguish if the displayed part of a map has been changed by program or by user interaction. Apparently, MKMapView objects do not tell me so, i.e. regionDidChangeAnimated is called in both cases without an indication why.
But since MKMapView is a subclass of UIView, and this one of UIResponder, one can implement the methods touchesBegan:withEvent: and touchesEnded:withEvent: to find out, if the map has been touched during the change of the displayed region.
If so, one can assume that the change in the displayed region was caused by user interaction. Of course you can be more specific if you investigate the set of touches and the event type of these methods more precisely.
I am such a plank sometimes writing problems can help. I simply removed the regionDidChangeAnimated as I have no need for it and the code that was present there I moved to my gesture which was to removeAnnotations before re-adding them doh!
Is it possible to animate changes to the coordinates of an annotation on an MKMapView in iOS? Nothing in the API seems to indicate that this is possible, however apps like Uber seem to do this when showing car locations in their map. Perhaps they are calling setCoordinate: multiple times over a short time to give the appearance of animation taking place?
I've added some MKPolygons to my MKMapView and they are displayed just fine by the MKMapView. If I now enable the userLocation for this MKMapView and the user grants permission for his location, no delegates are called and no overlays are drawn. After the next viewDidLoad the delegates work fine again and all the overlays are displayed.
So the problem only seems to appear, if the user is asked to grant permission for his location.
I hope somebody has an explanation/solution for this strange behavior, thanks.
Update
As I found out, it has nothing todo with the user location. Somehow the MKMapView is not calling it's delegates for drawing the overlays, but only if it's the initial view during the first app start. After that everthing works.
Simply move the setup code into its own method and call that both from viewDidLoad and one of the user tracking delegate methods like mapView:didChangeUserTrackingMode:animated: or mapViewWillStartLocatingUser:.
I am working on an application which use user location updates, I have got the current latitude and longitude and display the current location of the user and annotate the pin, However I need help regarding moving a pin when user changes his location or when user moves and get new latitude and longitude the pin should also move to that position.
To show the current location, you could just set showsUserLocation to YES and let the map show the blue dot for you.
If you want to show your own annotation instead and have it move automatically, implement setCoordinate: in the class that implements the MKAnnotation protocol.
Then when the coordinates change, update the annotation's coordinate and the map view will automatically (via KVO) move the annotation's view/pin.
You could also remove the annotation and create a new one at the new location but that can result in flicker.
If you are using Core Location to get location updates, you would update the annotation's coordinates in the locationManager:didUpdateToLocation:fromLocation: delegate method.