Will
Will

Reputation: 3044

MKMap cannot set the region in the ViewDidLoad/ViewWillAppear

I am trying to set the coordinates and region for a MKmap. The code that I have written work if I put it in the viewDidAppear however I do not want it to be in this method as I do not want it to be set every time the view appears.

This is the code that im trying to implement in these methods

//set the map delegate
MapView.delegate = (id)self;

//set the co-ords
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = LAT_POSN;
zoomLocation.longitude= LON_POSN;

//create region
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, startZoom, startZoom);
MKCoordinateRegion adjustedRegion = [MapView regionThatFits:viewRegion];
[MapView setRegion:adjustedRegion animated:YES];

EDIT: startZoom is a constant and I have logged it to make sure it there before setting the region

I have tried using

if (self.isMovingToParentViewController )

To get this to run the first time the view is called but it still shows the same result.

This is what it should look like.

should look like

But this is what im getting.

bad image

Does anyone know why this might be? Thanks

Answer: I used tkanzakic answer To make sure that some of my code was only used once. Also the reason that the region wasnt being set was that it didnt like this line of code.

MKCoordinateRegion adjustedRegion = [MapView regionThatFits:viewRegion];

Upvotes: 2

Views: 502

Answers (2)

Firoze Lafeer
Firoze Lafeer

Reputation: 17143

The issue here is in calling -[MKMapView regionThatFits:].

When you set the region for a map view, the view usually has to adjust your region a little to make it fit correctly within its bounds. Usually the aspect ratio of the region you specified doesn't match the aspect ratio of the actual view, for example.

If you really need to know the adjusted region before you set it, you can use -[MKMapView regionThatFits:]. The problem with doing that too early (e.g, in viewDidLoad) is that the map view calculates the "region that fits" according to it's own size on screen. That size may not be correct or isn't meaningful, in the case of autolayout, until the actual layout happens. So when viewDidLoad is called, the map view probably doesn't know its correct actual size yet.

From your code, it doesn't seem like you hold onto the adjustedRegion for very long, other than to just pass it right back to the map view. So you can omit that and just do this instead:

[mapView setRegion:viewRegion animated:NO];

Then the mapview will adjust that region, as needed. Later if you need to know what the adjusted region is, you can ask the map view for that later (in viewDidAppear: or some other time after the layout has happened).

Upvotes: 1

tkanzakic
tkanzakic

Reputation: 5499

I don't know why this code do not works in the viewDidLoad method, but to avoid that your code get fired every time the view appears you can include a static variable (or an attribute or a property if you don't want to use a static variable), like this:

- (void)viewDidAppear:(BOOL)animated
{
    static BOOL isFirstLoad = YES;
    if (isFirstLoad) {
        // Put your code here
        isFirstLoad = NO;
    }

    [super viewDidAppear:animated];
}

this will guaranteed that your code only run once.

Upvotes: 0

Related Questions