The below code is the method I've been using to zoom into the user's location, but then stop it from continuously re-zooming to it once the user moves the map. The problem with this method is that when it asks permission for userlocation data in the app, and I select yes, it doesn't do anything. I have to leave the page and return before it zooms correctly.
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([self.mapView showsUserLocation])
{
MKCoordinateRegion region;
region.center = self.mapView.userLocation.coordinate;
MKCoordinateSpan span;
span.latitudeDelta = .50; // Change these values to change the zoom
span.longitudeDelta = .50;
region.span = span;
[self.mapView setRegion:region animated:YES];
self.mapView.showsUserLocation = NO;}
}
The above method should be monitoring for user location changes and then set the location once it's found. I then set a condition in the if statement to make it stop -- otherwise it keeps moving back to the userlocation when you move the map around.
It sounds to me like self.mapView.showsUserLocation is set to FALSE when the popup appears because it doesn't know the user's location yet. To get around this problem, I would advise just using your own variable. Create a global boolean in this class and use it instead of self.mapView.showsUserLocation. Also, make sure that this function is, in fact, being called after the user agrees to the popup. Have you been NSLogging?
Related
I am working with map. I have a problem. I used following code to Zoom from the reference of this link in stackOverFlow
It's Easy to Zoom map.
But now,
I can't zoom in and out map. it means i cant change or find another place. it's only focus on current location. It's behave like an image Fix are. I can't understand what to do?
Please Help.
My Code as Follow.
- (void) viewDidLoad
{
[self.mapView.userLocation addObserver:self
forKeyPath:#"location"
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
context:nil];
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
MKCoordinateRegion region;
region.center = self.mapView.userLocation.coordinate;
MKCoordinateSpan span;
span.latitudeDelta = 1; // Change these values to change the zoom
span.longitudeDelta = 1;
region.span = span;
[self.mapView setRegion:region animated:YES];
}
I think the problem is that you are listening to user location changes (which most probably happening multiple times per second) and you are setting the map region to that region.
What you need to do is add a button on the map (like top left corner in Apple maps) which will toggle the map-mode to either free look or fixed to user location.
When the user press the button, you either remove/add the KVO. or toggle a boolean flag in your code. When the flag is true, you don't change map region. Something like:
#implementation YourController{
BOOL _followUserLocation;
}
- (IBAction) toggleMapMode:(id)sender{
_followUserLocation = !_followUserLocation;
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if(_followUserLocation){
MKCoordinateRegion region;
region.center = self.mapView.userLocation.coordinate;
MKCoordinateSpan span;
// retain the span so when the map is locked into user location they can still zoom
span.latitudeDelta = self.mapView.region.span.latitudeDelta;
span.longitudeDelta = self.mapView.region.span.longitudeDelta;
region.span = span;
[self.mapView setRegion:region animated:YES];
}
}
#end
Maybe you don't want all this and all you need is:
// retain the span so when the map is locked into user location they can still zoom
span.latitudeDelta = self.mapView.region.span.latitudeDelta;
span.longitudeDelta = self.mapView.region.span.longitudeDelta;
I have a MKMapView and in the Map View "Show User Location" is set. The question if the app should use my location, I say yes. Then I see the blue bullet and I can zoom to the current location.
I read many other posts about this, but nothing solve the problem, that the user location won't zoom in automatically.
I want to have a zoom on startup if the user allows access the location, otherwise a defined coordinate should zoom in. (after, is the use allows the location, it can be updated, but should not set the center to the user location everytime I get updates on the location).
What are the steps to implement this behavior? I tried for example this: How do I zoom an MKMapView to the users current location without CLLocationManager? with the KVO but it does not work...
I hope someone has an idea?
Best Regards, Tim
Have you tried the delegate method mapView:didUpdateUserLocation:?
I used something like this in my code:
In the .h file:
#property (nonatomic, retain) CLLocation* initialLocation;
And in the .m file:
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
if ( !initialLocation )
{
self.initialLocation = userLocation.location;
MKCoordinateRegion region;
region.center = mapView.userLocation.coordinate;
region.span = MKCoordinateSpanMake(0.1, 0.1);
region = [mapView regionThatFits:region];
[mapView setRegion:region animated:YES];
}
}
you can do it like this in your viewDidLoad write this code
self.mapDetail.showsUserLocation = YES;
[self.mapDetail.userLocation addObserver:self
forKeyPath:#"location"
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
context:nil];
and this method will do the task
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
MKCoordinateRegion region;
region.center = self.mapDetail.userLocation.coordinate;
MKCoordinateSpan span;
span.latitudeDelta = 1; // Change these values to change the zoom
span.longitudeDelta = 1;
region.span = span;
[self.mapDetail setRegion:region animated:YES];
[self.mapDetail.userLocation removeObserver:self forKeyPath:#"location"];
}
I implemented the following MKMapView method, which runs after annotations are added. I have my MKMapView map (parishMap) set to "Shows user location" in Interface Builder, and upon loading the mapview, the blue dot always appears within a second or so on the mapview.
Here's the code I have in my Map View controller implementation:
// Center map on user location (initially)
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
for(MKAnnotationView *annotationView in views) {
if(annotationView.annotation == parishMap.userLocation) {
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.03;
span.longitudeDelta=0.03;
CLLocationCoordinate2D location=parishMap.userLocation.coordinate;
location = parishMap.userLocation.location.coordinate;
region.span=span;
region.center=location;
[parishMap setRegion:region animated:TRUE];
[parishMap regionThatFits:region];
}
}
}
When I open the mapview on my iPhone 4, the mapview always (and almost immediately) moves to center on the userLocation dot. However, when I open the mapview on an iPhone 3Gs or iPod Touch (2010), it doesn't center on the userLocation, but just stays at the default zoom/region I set for the map view.
Any ideas as to why this code won't work for non-iPhone 4 devices (they're all running 4.2.x latest iOS)?
This is probably an issue with the amount of time it takes for the GPS to lock a position on these different devices.
I'd recommend using CLLocationManager and its delegate methods to center the map.
You can start updating location by creating an instance of CLLocationManager, setting its delegate property to self and then implementing:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
Where you can center your map accordingly based on the latest location update.
have you tried using this code to center the map:
[mapView setCenterCoordinate:location animated:YES];
I'm not sure why it would work for iPhone 4 and not the others, but this is the code I use to adjust the region:
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(location, 0.03, 0.03);
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
[mapView setRegion:adjustedRegion animated:YES];
Try it that way and see how that works. The way you're doing the regionThatFits method, that's actually not supposed to be how the method is used. You can try commenting out that last line of your code, it should make no difference. Anyway, try it with the method I just gave and let me know if you have any questions.
I have a normal mapView, which can tell the users location, but when users location is located my map doesn't suddenly zoom in to the users location like Apples maps application.
Does anybody know how to implement this feature!
Implement the didUpdateUserLocation delegate method:
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region;
region.center = userLocation.location.coordinate;
MKCoordinateSpan span = { 1.0, 1.0 };
region.span = span;
[mapView setRegion:region animated:YES];
}
Make sure your map view's delegate is set.
I'm using map kit and showing user's location using "showsUserLocation"
I"m using following code to zoom to user's location, but not zooming. Its zooming to some location in Africa, though the user location on map is showing correct.
MKCoordinateRegion newRegion;
MKUserLocation* usrLocation = mapView.userLocation;
newRegion.center.latitude = usrLocation.location.coordinate.latitude;
newRegion.center.longitude = usrLocation.location.coordinate.longitude;
newRegion.span.latitudeDelta = 20.0;
newRegion.span.longitudeDelta = 28.0;
[self.mapView setRegion:newRegion animated:YES];
Why is user's location correctly showing and not zooming properly. Can some one correct me please?
mapView.userLocation is set to a location off the coast of Africa (0,0) when first instantiated. As a result, I do something like the following, which causes the zoom to occur when the annotation appears. Of course, this is just an example:
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views {
for(MKAnnotationView *annotationView in views) {
if(annotationView.annotation == mv.userLocation) {
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.1;
span.longitudeDelta=0.1;
CLLocationCoordinate2D location=mv.userLocation.coordinate;
region.span=span;
region.center=location;
[mv setRegion:region animated:TRUE];
[mv regionThatFits:region];
}
}
}
you can try:
mapView.userTrackingMode=YES;
mapView.userTrackingMode=NO;
UserTrackingMode will zoom to user Location.
Have you verified that the location returned by mapView.userLocation isn't at 0, 0?