2013-03-21 52 views
3

我一直有MKMapView(報告給蘋果,但沒有迴應)持續的內存泄漏問題,所以作爲解決方法,我試圖只分配一個MKMapView並重新使用而不是重新分配一個新的地圖。我遇到的問題是我還沒有能夠重置MKMapView到它開始的視圖。我想,因爲我從美國工作,我最初得到這樣一個觀點:MKMapView重置回到世界的視圖:被重新燒烤

map of USA http://www.cprince.com/stackoverflow/map1.png

有了這個代碼:

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按鈕,我得到如下圖(沒有驚喜但):

map of my home http://www.cprince.com/stackoverflow/map2.png

,當我離開導航(使用導航控制LER)從該視圖,然後重新進入視圖(viewWillAppear中再次呼籲,但這次重新使用的MKMapView以前分配的),我得到下面的地圖視圖:

map of ocean http://www.cprince.com/stackoverflow/map3.png

,當然還有我應該得到原來的默認區域,因爲viewWillAppear中的這一部分:

 defaultRegion = MKCoordinateRegionMake(map.centerCoordinate, MKCoordinateSpanMake(180, 360)); 
    } else { 
     [map setRegion:defaultRegion animated:YES]; 
    } 

如果做setRegion的addSubview或之前之後不要緊。也就是說,下面的改變不能解決probelem:

- (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]; 
} 

,等到地圖上查看美國定居之前,我按一下按鈕,問題是一樣的。

我正在使用iOS 6.1.2和XCode 4.6。

(完整的XCode項目可在http://www.cprince.com/stackoverflow/Map.zip)。

想法?

第一個變化

我做了defaultRegion靜態,而不是一個實例變量,這不會發生顯着變化的情況。 (我在下面報告了默認區域的lat/long)。這裏的結果在地圖:

map of ocean http://www.cprince.com/stackoverflow/map4.png

爲了清楚起見,因爲就目前的代碼是:

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]; 
} 
+0

你嘗試設置動畫屬性設置爲否的區域? – Adis 2013-03-21 22:25:20

+0

您是否檢查過首次加載頁面時defaultRegion中的值?也許你並沒有讓自己認爲的那個地區成爲現實。例如,如果它可能失敗,因爲你不在(0,0),而是給它一個180x360的範圍,所以它會進入無效座標。 – Craig 2013-03-21 23:37:31

+0

將設置爲動畫設置爲NO的區域不會改變情況。剛剛嘗試過。 – 2013-03-22 00:49:03

回答

3

如果你讓你的視圖控制器爲MKMapView一個delegate和實施regionDidChangeAnimated,你您會發現,當您第一次創建地圖視圖時,centerCoordinate30, -40,但隨後會設置爲37.178181, -96.054581(對於美國用戶至少)。在創建地圖視圖後,您顯然不能立即依靠region和/或centerCoordinate。你必須給它一個機會來重置它的region,這顯然是異步發生的。

如果你想保存MKMapView集後defaultRegion它的第一次,設置MKMapView,然後的delegate財產實施:

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 
{ 
    static BOOL firstTime = YES; 
    if (firstTime) 
    { 
     defaultRegion = mapView.region; 
     firstTime = NO; 
    } 
} 

注意,在viewWillDisappear,因爲你做了你的地圖一個static,請確保nil地圖的delegate(因爲那個舊的視圖控制器將消失)。如果您希望繼續將視圖控制器的新實例設置爲MKMapViewDelegate,那麼當您將地圖視圖重新添加到細節視圖控制器的新實例時,請再次設置delegate


老答案:

當你設置defaultRegion,這是一個實例變量。因此,當你忽視這個觀點時,這是失敗的。當您回到地圖(即firstTimeNO)時,defaultRegion從不初始化,因此爲0,0,因此位於大西洋中部。

你顯然沒有保存defaultRegion(通常你會有一個協議把它傳遞迴主視圖控制器),這使得應用程序很難知道當你選擇再次掌握視圖。

+0

看到我上面的評論。是的,這應該起作用了。但事實並非如此。 – 2013-03-22 01:10:37

+0

@ChrisPrince好吧,你現在(通過使'defaultRegion' static)正確地保存'defaultRegion'。接下來的問題是,在創建'MKMapView'後立即設置'defaultRegion',但設置區域覆蓋美國的過程是異步發生的。看到我更新的答案。 – Rob 2013-03-22 01:35:29

+0

@ChrisPrince我已經添加了保存'defaultRegion'的代碼。 – Rob 2013-03-22 01:43:24