MKMapViewでメモリリークの問題が継続的に発生しているため(Appleに報告されましたが、応答がありません)、回避策として、新しいマップを再割り当てする代わりに、1つのMKMapViewを割り当ててそのマップを再利用しようとしました。これで発生している問題は、MKMapViewを元のビューにリセットすることがまだできないことです。私はアメリカで働いているので、最初は次のような見方をしていると思います。
(出典:cprince.com)
このコードで:
static MKMapView *map = nil;
- (void) showUserLocation {
[map setShowsUserLocation:YES];
CLLocationCoordinate2D coord;
coord.latitude = 39.0; // changed from original coords
coord.longitude = -105.0;
MKCoordinateRegion r = MKCoordinateRegionMakeWithDistance(coord, 1000, 1000);
[map setRegion:r animated:YES];
}
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (! map) {
CGRect r = CGRectMake(20, 50, 196, 75);
map = [[MKMapView alloc] initWithFrame:r];
defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360));
} else {
[map setRegion:defaultRegion animated:YES];
}
[self.view addSubview:map];
}
- (IBAction)annotateMap:(id)sender {
[self showUserLocation];
}
annotateMapを呼び出すボタンをクリックすると、次のマップが表示されます(まだ驚きはありません)。
(出典:cprince.com)
次に、このビューから(ナビゲーションコントローラーを使用して)移動してからビューに再度入ると(viewWillAppearが再度呼び出されますが、今回は以前に割り当てられたMKMapViewを再利用します)、次のマップビューが表示されます。
(出典:cprince.com)
そしてもちろん、viewWillAppearのこの部分のために、元のデフォルト領域を取得する必要があります。
defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360));
} else {
[map setRegion:defaultRegion animated:YES];
}
addSubviewの後または前にsetRegionを実行するかどうかは関係ありません。つまり、以下の変更は問題を修正しません。
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
BOOL firstTime = NO;
if (! map) {
firstTime = YES;
CGRect r = CGRectMake(20, 50, 196, 75);
map = [[MKMapView alloc] initWithFrame:r];
defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360));
}
[self.view addSubview:map];
if (! firstTime) {
[map setRegion:defaultRegion animated:YES];
}
}
MKMapRectWorldを使用しても効果はありません。
defaultRegion = MKCoordinateRegionForMapRect(MKMapRectWorld);
この問題は、MKMapViewのある種の競合状態によるものでもありません。ボタンのハンドラーを変更した場合:
- (IBAction)annotateMap:(id)sender {
defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360));
[self showUserLocation];
}
ボタンをクリックする前に、マップがUSAビューに確定するまで待ってください。問題は、同じです。
iOS6.1.2とXCode4.6を使用しています。
(完全なXCodeプロジェクトはhttp://www.cprince.com/stackoverflow/Map.zipで入手できます)。
考え?
最初の変更
defaultRegionをインスタンス変数ではなく静的にしたのですが、これによって状況が大きく変わることはありません。(以下のデフォルト領域の緯度/経度を報告しました)。マップの結果は次のとおりです。
(出典:cprince.com)
わかりやすくするために、現在のコードは次のとおりです。
static MKMapView *map = nil;
static MKCoordinateRegion defaultRegion;
- (void) showUserLocation {
[map setShowsUserLocation:YES];
CLLocationCoordinate2D coord;
coord.latitude = 39.0; // changed from original
coord.longitude = -105.0;
MKCoordinateRegion r = MKCoordinateRegionMakeWithDistance(coord, 1000, 1000);
[map setRegion:r animated:YES];
}
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
BOOL firstTime = NO;
if (! map) {
firstTime = YES;
CGRect r = CGRectMake(20, 50, 196, 75);
map = [[MKMapView alloc] initWithFrame:r];
defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360));
NSLog(@"defaultRegion: center: lat: %f, long: %f; span: %f dlat: dlong: %f", defaultRegion.center.latitude, defaultRegion.center.longitude, defaultRegion.span.latitudeDelta, defaultRegion.span.longitudeDelta);
//defaultRegion = MKCoordinateRegionForMapRect(MKMapRectWorld);
}
[self.view addSubview:map];
if (! firstTime) {
NSLog(@"defaultRegion: center: lat: %f, long: %f; span: %f dlat: dlong: %f", defaultRegion.center.latitude, defaultRegion.center.longitude, defaultRegion.span.latitudeDelta, defaultRegion.span.longitudeDelta);
[map setRegion:defaultRegion animated:YES];
}
}
- (IBAction)annotateMap:(id)sender {
//defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360));
[self showUserLocation];
}