I'm working on a 3-tabbed iPhone app., where I want each tab's view to look like it shares the same map. So at the moment, I'm just trying to figure out how to reset each view's MKMapView's region when one clicks on a new tab. [In other words, if you're on tab 1 and zoomed all the way in on a spot, then click on tab 2, I want it to show the same, zoomed in map.]
To do this, I have an MKCoordinateRegion in the app delegate that each view saves to before it goes away, and that each new view reads from before it is viewed.
[In other words, my app delegate is my TabBarControllerDelegate and I've overridden tabBarController: shouldSelectViewController:. This function is called after someone clicks on a tab button, and before the new tab's view's viewWillAppear: function is called. So, in this function, I save the region of the current view to my AppDelegate::MKCoordinateRegion variable, and then let the new view's viewWillAppear: (or viewDidLoad:) get called. Then, in the new view's viewWillAppear:, I get the MKCoordinateRegion from the app delegate, and assign it to my new view's region.]
However, the values from MKMapKit::setRegion: don't seem to be consistent and I don't know if I'm just doing something wrong, missing something entirely, or if something else is going on.
I've only been doing iPhone dev. (and Obj-c, etc.) for about 2 weeks now, so this very well just could be a newby mistake. And if so, I will go ahead and apologize now for wasting your time. Nonetheless, here's some code (and I've left in the comments I was using...just in case you try running it yourself):
iPhoneTestAppDelegate.h
...
@interface iPhoneTestAppDelegate : NSObject
{
UIWindow* _window;
UITabBarController* _tabBarController;
SubViewController* _subViewController;
MKCoordinateRegion _mapRegion;
}
@property (nonatomic, retain) IBOutlet UIWindow* window;
@property (nonatomic, retain) IBOutlet UITabBarController* tabBarController;
@property (nonatomic, retain) IBOutlet SubViewController* subViewController;
@property (nonatomic, assign) MKCoordinateRegion mapRegion;
@end
iPhoneAppDelegate.m
...
static CLLocationDegrees INITIAL_LATITUDE = 40.754019;
static CLLocationDegrees INITIAL_LONGITUDE = -73.973351;
static CLLocationDegrees INITIAL_SPAN_LAT_DEG = .10767;
static CLLocationDegrees INITIAL_SPAN_LONG_DEG = .109863;
...
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
NSLog(@"Begin");
// initialize the delegate's region
MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}};
region.center.latitude = INITIAL_LATITUDE;
region.center.longitude = INITIAL_LONGITUDE;
region.span.latitudeDelta = INITIAL_SPAN_LAT_DEG;
region.span.longitudeDelta = INITIAL_SPAN_LONG_DEG;
self.mapRegion = region;
self.tabBarController.delegate = self;
[self.window addSubview:self.tabBarController.view];
}
- (BOOL)tabBarController:(UITabBarController *)tabBarController
shouldSelectViewController:(UIViewController *)viewController
{
NSLog(@"in UITabBarControllerDelegate: shouldSelectViewController:");
if([tabBarController.viewControllers indexOfObject:viewController] !=
[tabBarController selectedIndex])
{
NSLog(@"different view selected");
BaseViewController* currView = (BaseViewController *)[tabBarController selectedViewController];
NSLog(@"%f %f %f %f",
self.mapRegion.center.latitude, self.mapRegion.center.longitude,
self.mapRegion.span.latitudeDelta, self.mapRegion.span.longitudeDelta);
NSLog(@"%f %f %f %f",
currView.mapView.region.center.latitude, currView.mapView.region.center.longitude,
currView.mapView.region.span.latitudeDelta, currView.mapView.region.span.longitudeDelta);
self.mapRegion = currView.mapView.region;
NSLog(@"%f %f %f %f",
self.mapRegion.center.latitude, self.mapRegion.center.longitude,
self.mapRegion.span.latitudeDelta, self.mapRegion.span.longitudeDelta);
}
else
NSLog(@"same view selected");
return YES;
}
BaseViewController.m
...
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"Base: viewDidLoad");
iPhoneTestAppDelegate* appDelegate = (iPhoneTestAppDelegate *)
[[UIApplication sharedApplication] delegate];
[self.mapView setDelegate:self];
//[self.mapView setRegion:appDelegate.mapRegion animated:YES];
[self.mapView setRegion:[self.mapView regionThatFits:appDelegate.mapRegion]];
NSLog(@"---------------------");
NSLog(@"%f %f %f %f",
appDelegate.mapRegion.center.latitude, appDelegate.mapRegion.center.longitude,
appDelegate.mapRegion.span.latitudeDelta, appDelegate.mapRegion.span.longitudeDelta);
NSLog(@"---------------------");
NSLog(@"%f %f %f %f",
self.mapView.region.center.latitude, self.mapView.region.center.longitude,
self.mapView.region.span.latitudeDelta, self.mapView.region.span.longitudeDelta);
NSLog(@"---------------------");
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"Base: viewWillAppear");
iPhoneTestAppDelegate* appDelegate = (iPhoneTestAppDelegate *)
[[UIApplication sharedApplication] delegate];
//[self.mapView setRegion:appDelegate.mapRegion animated:YES];
[self.mapView setRegion:[self.mapView regionThatFits:appDelegate.mapRegion]];
NSLog(@"*********************");
NSLog(@"%f %f %f %f",
appDelegate.mapRegion.center.latitude, appDelegate.mapRegion.center.longitude,
appDelegate.mapRegion.span.latitudeDelta, appDelegate.mapRegion.span.longitudeDelta);
NSLog(@"*********************");
NSLog(@"%f %f %f %f",
self.mapView.region.center.latitude, self.mapView.region.center.longitude,
self.mapView.region.span.latitudeDelta, self.mapView.region.span.longitudeDelta);
NSLog(@"*********************");
}
...
Now, the first thing I notice when I run this is that when the initial view's viewDidLoad: is called, the delegate's region and my new view's region are the same (after I call setRegion:). However, after setRegion: is called in viewWillAppear:, my view's MKMapView's region is no longer equal to the delegates. Somehow, the exact same code in viewDidLoad: produces a different result when run in viewWillAppear:! Shouldn't that not be the case? Why does calling setRegion: from viewWillAppear: change the values of my view's MKMapView's region? Does this have something to do with regionThatFits: being called internally? I don't get it!
However, I kind of think that if I can figure that part out, I might be able to figure out the other issues; so, I won't go into more details here. But, if you make a quick app. with these functions and run it, you'll see the issues. Mainly, the view's maps are occasionally in synch, but as you zoom and move around (and keep switching back and forth between tabs), the span starts to shrink and each new tab press just keeps zooming me farther and farther out.
Note: I'm only running this on the simulator (3.0) [I don't have the hardware yet], so I don't know if that has anything to do with it. But, I kind of doubt it.
Anyway, thanks for any help you can offer. I really appreciate it.