2009-09-02 7 views
2

Je travaille sur une application iPhone à 3 onglets, où je veux que la vue de chaque onglet ressemble à la même carte. Donc pour le moment, j'essaie juste de comprendre comment réinitialiser la région de MKMapView de chaque vue quand on clique sur un nouvel onglet. [En d'autres termes, si vous êtes sur l'onglet 1 et que vous faites un zoom avant sur un point, cliquez sur l'onglet 2, je veux qu'il affiche la même carte zoomée.]MKMapView setRegion: comportement étrange?

Pour cela, avoir une MKCoordinateRegion dans le délégué de l'application que chaque vue enregistre avant qu'elle ne disparaisse, et que chaque nouvelle vue lise avant qu'elle ne soit vue.

[En d'autres termes, mon délégué d'application est mon TabBarControllerDelegate et j'ai remplacé tabBarController: shouldSelectViewController :. Cette fonction est appelée après que quelqu'un a cliqué sur un bouton de tabulation, et que la fonction viewWillAppear: de la vue du nouvel onglet est appelée. Ainsi, dans cette fonction, j'enregistrer la région de l'affichage en cours dans ma variable AppDelegate :: MKCoordinateRegion, puis laisser afficher la nouvelle vue viewWillAppear: (ou viewDidLoad :). Ensuite, dans la vue newWillAppear de la nouvelle vue, j'obtiens le MKCoordinateRegion du délégué de l'application et l'affecte à la région de ma nouvelle vue.]

Cependant, les valeurs de MKMapKit :: setRegion: ne semblent pas cohérentes et Je ne sais pas si je fais quelque chose de mal, si je manque complètement quelque chose ou si quelque chose d'autre se passe.

Je n'ai fait que des dev de l'iPhone. (et Obj-c, etc.) pour environ 2 semaines maintenant, donc cela très bien pourrait être une erreur nouvelle. Et si c'est le cas, je vais m'excuser maintenant pour avoir perdu votre temps. Quoi qu'il en soit, voici un code (et je suis parti dans les commentaires que j'utilisais ... juste au cas où vous essayez d'exécuter vous-même):

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(@"*********************"); 
} 
... 

maintenant, la première chose que je remarque quand je ru n c'est que lorsque la vue initiale viewDidLoad: est appelée, la région du délégué et la région de ma nouvelle vue sont les mêmes (après avoir appelé setRegion :). Cependant, après que setRegion: est appelée dans viewWillAppear :, la région de MKMapView de ma vue n'est plus égale aux délégués. D'une certaine manière, le même code dans viewDidLoad: produit un résultat différent lorsqu'il est exécuté dans viewWillAppear :! Cela ne devrait-il pas être le cas? Pourquoi appeler setRegion: from viewWillAppear: modifie les valeurs de la région MKMapView de ma vue? Est-ce que cela a quelque chose à voir avec regionThatFits: être appelé en interne? Je ne comprends pas! Cependant, je pense en quelque sorte que si je peux comprendre cette partie, je pourrais être en mesure de comprendre les autres problèmes; donc, je ne vais pas entrer dans plus de détails ici. Mais, si vous faites une application rapide. avec ces fonctions et exécutez-le, vous verrez les problèmes. Principalement, les cartes de la vue sont parfois synchronisées, mais lorsque vous zoomez et bougez (et que vous passez d'un onglet à l'autre), l'intervalle commence à rétrécir et chaque nouvelle pression sur l'onglet continue de me zoomer de plus en plus loin.

Note: Je ne fais que cela sur le simulateur (3.0) [je n'ai pas encore le matériel], donc je ne sais pas si cela a quelque chose à voir avec ça. Mais, j'en doute un peu.

Quoi qu'il en soit, merci pour toute aide que vous pouvez offrir. J'apprécie vraiment cela.

Répondre

3

Je travaille sur un problème similaire avec la mise en œuvre d'une fonction zoom-à-ajustement autour d'un ensemble de points.La seule aide que je peux vous donner pour le moment est que oui, regionThatFits: est en fait appelé en interne. J'appelle setRegion avec une région qui correspond exactement à tous les points, de sorte qu'il doit y avoir un point exactement sur le bord de chaque côté, ainsi que des points à l'intérieur de la zone visible. La région que la mapview a réellement après l'appel setRegion est différente, mais exactement la même que la région que vous obtenez si vous appelez regionThatFits: avec la région que je veux utiliser. Cette région est généralement un peu plus grande que ce que je veux.

Je l'ai travaillé sous la théorie que regionThatFits essaye simplement de capturer le rapport d'aspect, et bungle la correction de rapport d'aspect. Cependant, deux choses semblent indiquer que ce n'est pas la seule chose qui se passe: d'abord, le rapport d'aspect de la région retournée par regionThatFits est et non le même que le rapport d'aspect de la vue de la carte. Deuxièmement, lorsque j'utilise mon propre code de correction d'aspect pour obtenir exactement le même rapport d'aspect que la sortie de regionThatFits, j'obtiens toujours la région de taille erronée de regionThatFits (et la mapView).

Jusqu'à présent, MapKit est assez exaspérant.