0

I currently have a map displaying 10 or so co ordinates.The map gets the users location and centers on it as soon as it is opened. When panning the page or zooming different levels it eventually resets and centers in on the first position of the user.I have tried "stopupdating location" and Animated as "NO".I can not get it to stay in positon when the user scrolls the map.

- (void)viewDidLoad {
[super viewDidLoad];
self.petrolMap.delegate = self;
self.location = [[CLLocationManager alloc] init];
[location setDelegate:self];
[location setDistanceFilter:0];  // Do not apply a distance filter to the map
[location setDesiredAccuracy:kCLLocationAccuracyBest]; // Use the best accuracy possible when displaying the map
petrolMap.delegate=self; // Display on "Petrol Map" , the mapview for the application}



-(void) mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{MKCoordinateRegion mapRegion;
mapRegion.center = petrolMap.userLocation.coordinate;
mapRegion.span.latitudeDelta=0.02;
mapRegion.span.longitudeDelta=0.02;
[petrolMap setRegion:mapRegion animated:NO];}
James New
  • 91
  • 4
  • 9

2 Answers2

1

Your 'location' is a location manager, when it works out where you are it'll send its delegate

locationManager:didUpdateToLocation:fromLocation:

which you don't seem to have, so all those settings you're doing to 'location' are wasted (as far as the code you've given us, it may be useful elsewhere) and telling it to stop tracking the user is of no use.

"(void) mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{MKCoordinateRegion mapRegion;" is what petrolMap is sending to its delegate. Somewhere you must have set petrolMap to track the user, it can be done in the .xib.

Anyway, to stop petrolMap sending messages make sure you run

[petrolMap setUserTrackingMode:MKUserTrackingModeNone animated:NO];

Some extra notes:

  • Within didUpdateUserLocation you don't need to refer to petrolMap directly because the mapView parameter is set to which ever MKMapView sent the message.

  • Also within didUpdateUserLocation you are using petrolMap's userLocation instead of the parameter userLocation, and even building your region. The entire code for that function could be one line

    [mapView setRegion:mapRegion animated:NO];
    
  • 'Animated' controls how the change in region is done. Yes means it will slide between locations, No means it will snap from one to the other instantly, either way the map will move to the new region.

  • Your viewDidLoad method could be cut to two lines like follows

    [super viewDidLoad];
    self.petrolMap.delegate = self;
    

Addendum:

locationManager:didUpdateToLocation:fromLocation 

is deprecated in iOS6.

thandasoru
  • 1,558
  • 2
  • 15
  • 41
Craig
  • 8,093
  • 8
  • 42
  • 74
  • Thanks for the tips. After removing the referral to petrol map , my map no longer automatically zooms in on the user (Point 1 you gave).I have implemented the [petrolMap setUserTrackingMode:MKUserTrackingModeNone animated:NO]; an it still snaps back to position. I implemented it within did update user location? is this correct? – James New Feb 28 '12 at 15:28
  • the updating stops if i remove the mkmapview reference u suggested but stops the users location being zoomed in on automatically.Oh and my tracking is done via the xib – James New Feb 28 '12 at 15:28
  • My point 1 was that you should use the variable "mapView" in place of "petrolMap", did you remove the setRegion line altogether? See point 2. You still sound like you've got two things trying to set the location. If you have turned on tracking via the xib you don't need use a delegate in viewDidLoad and you don't need to setRegion yourself. I think MKMapView turns off tracking mode once you start dragging on the map, you'll then need some button on screen if you want to turn tracking back on. You can remove all the code you quoted if you have the MKMapView set to track the user via the xib. – Craig Feb 29 '12 at 01:43
  • I removed all of the suggested , and it still works. It is not snapping back to the user , but there is no zoom automatically on the users location at the start. How do i do this? – James New Feb 29 '12 at 17:40
  • That's what setting the tracking mode in the xib will do for you. Are you trying in the simulator or on a device? – Craig Feb 29 '12 at 18:34
  • It tracks the user (Blue dot) but i had it so it automatically zooms in on the user (saves them pinching to zoom) o, instead its just zoomed out on the UK – James New Mar 02 '12 at 17:05
  • There's a difference between showing the user and tracking the user. is it possible you've only turned on the showing part? If you set [petrolMap setUserTrackingMode:MKUserTrackingModeFollow animated:NO]; that's start the map moving along with the user or you can set the petrolMap's delegate to self and use the one line version of didUpdateUserLocation that I gave above. – Craig Mar 02 '12 at 18:56
  • it follows because the blue rings are animated when it updates , just need to automatically zoom in on the user when opening the program! – James New Mar 02 '12 at 21:00
  • sorry about all the questions , uni programming assignment and first time ive used objective c! – James New Mar 02 '12 at 21:00
  • So have you tried the one line version I gave you? And when you want it to stop following the user (as in moving the map so that the user is shown in the middle) you call [petrolMap setUserTrackingMode:MKUserTrackingModeNone animated:NO]; – Craig Mar 04 '12 at 08:32
  • Ive inserted the one line version yes , the user is shown in the middle! I am referring to ZOOMING in automatically on the user? – James New Mar 04 '12 at 19:26
  • Yup, the one liner 'setRegion' code should set a small region if iOS really knows where the device is. It'll give you a large region if it is unsure. As the device gets better and better information about where it is the region you are given in didUpdateUserLocation gets smaller and smaller, hence the zooming. Maybe you should put in a print statement in didUpdateUserLocation so you can see the region that gets given to you. If the region isn't changing then the device isn't getting any better knowledge on where it is. – Craig Mar 05 '12 at 00:23
  • Sorry im getting confused to be honest , with all the changes here is the code i have now – James New Mar 05 '12 at 15:32
  • - (void)viewDidLoad { [super viewDidLoad];self.petrolMap.delegate = self; self.location = [[CLLocationManager alloc] init]; } -(void) mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation { [petrolMap setUserTrackingMode:MKUserTrackingModeNone animated:NO]; } – James New Mar 05 '12 at 15:40
  • Think about what you're doing there, when the map view gets an update on the user location you're turning off the tracking mode but using that location. That's not what you want is it? in the UpdateUserLocation method you want to zoom in based on the location and region it gives you, you have a line that does that. [mapView setRegion:mapRegion animated:NO]; put that in your didUpdateUserLocation function and put the line that stops the tracking somewhere else. *OR* avoid all of this and just set the tracking mode to MKUserTrackingModeFollows and don't do any setRegion stuff at all. – Craig Mar 05 '12 at 18:18
  • But wont what tracking modefollows snap back to user location when someone moves around or zooms in/out on the map? – James New Mar 06 '12 at 12:49
  • The mode gets taken away when the user starts dragging the map with their fingers. Try it. – Craig Mar 06 '12 at 17:49
  • I put the first two options in that you suggested in your last comment , and it still seems to snap back to position :/ – James New Mar 07 '12 at 11:47
  • Think about what is happening there. Every time the MKMapView gets a location you're zooming in to it using setRegion. And at some point you want that to stop. So either you make the MKMapView stop getting location information or you choose not to setRegion sometime. Check out MKMapView's showsUserLocation property for the former, and you must be able to work out the latter yourself. What do you do IF you want something to happen sometimes and sometimes you want something ELSE to happen? – Craig Mar 07 '12 at 19:59
  • It's been nearly two weeks now, did you solve it? Here's another person asking a similar question http://stackoverflow.com/questions/9637737/map-view-always-center-map-on-my-location – Craig Mar 18 '12 at 21:04
0

Unfortunately this is a few years to late for you James - but hopefully it'll help others who are stuck in this situation (like myself).

I ended up adding...

[self.mapView setUserTrackingMode:MKUserTrackingModeFollow];

Into my -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation

You should normally add "animated:YES" at the end, but this again would ping it back to my current location, even if I changed the commander to "NO" - so tried deleting it and it worked!!!

Just for reference my whole code became:

-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{

if(userLocationShown) return;

MKCoordinateRegion region;
MapView.showsUserLocation = YES;
region.center.latitude = MapView.userLocation.coordinate.latitude;
region.center.longitude = MapView.userLocation.coordinate.longitude;
region.span = MKCoordinateSpanMake(0.02,0.02);
[MapView setRegion:region animated:YES];

[self.mapView setUserTrackingMode:MKUserTrackingModeFollow];
[locationManager startUpdatingLocation];
[locationManager stopUpdatingLocation];

userLocationShown = YES;

and I added...

- (void)viewDidLoad {
[super viewDidLoad];

[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
MapView.delegate = self;
Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
  • you'd think animated:NO would work the same as the omitted version of that method... but sure enough, fixed the problem for me too. – Chris J Apr 21 '16 at 07:22