2013-03-21 2 views
3

У меня проблемы с утечкой памяти в MKMapView (сообщается Apple, но ответа нет), и я старался просто выделить один MKMapView и повторно использовать это вместо перераспределения новой. Проблема, с которой я столкнулся, заключается в том, что мне еще не удалось сбросить MKMapView до того, с чего он начинается. Я предполагаю, потому что я работаю из США, я сначала получить представление, как это:MKMapView снова возвращается к мировоззрению: Rebaked

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

тогда, когда я уйду (с помощью элемента управления навигации Лер) с этой точки зрения, а затем повторно ввести вид (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

+0

Вы проверили значения по умолчанию, которые вы делаете, когда страница загружается первой? Возможно, вы не делаете регион, который, по вашему мнению, вы. Например, если это может быть неудачно, потому что вы не в (0,0), но даете ему интервал 180x360, чтобы он попадал в неверные координаты. – Craig

+0

Настройка области с анимированным набором на NO не меняет ситуацию. Просто попробовал это. –

ответ

3

Если вы сделаете ваш контроллер вид delegate для MKMapView и реализации regionDidChangeAnimated, вы Посмотрим, что при первом создании вида карты centerCoordinate будет 30, -40, но впоследствии он будет установлен на 37.178181, -96.054581 (для пользователей США, по крайней мере). Вы, по-видимому, не можете положиться на region и/или centerCoordinate сразу после создания вида карты. Вы должны дать ему возможность сбросить region, что, по-видимому, происходит асинхронно.

Если вы хотите сохранить defaultRegion после того, как MKMapView устанавливает его в первый раз, установите delegate свойство MKMapView, а затем реализовать:

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

Примечание, на viewWillDisappear, так как вы сделали карту a static, убедитесь, что nil карта delegate (так как этот старый контроллер будет исчезать). Если вы хотите, чтобы ваш новый экземпляр контроллера представления был MKMapViewDelegate, просто установите delegate еще раз, когда вы снова добавите представление карты в свой новый экземпляр вашего контроллера подробного представления.


Старый ответ:

При установке defaultRegion, это переменная экземпляра. Таким образом, это потеряно, когда вы отклоняете представление. Когда вы возвращаетесь к карте (то есть firstTime - NO), defaultRegion никогда не инициализируется и, следовательно, составляет 0,0 и, следовательно, находится в середине Атлантического океана.

Вы, очевидно, не сохраняете defaultRegion (как правило, у вас есть протокол, чтобы передать это обратно контроллеру главного представления), что затрудняет для приложения знать, что делать, когда вы выбираете элемент в снова просмотрите мастер.

+0

Смотрите мои комментарии выше.Да, это должно сработать. Но это не так. –

+0

@ChrisPrince Хорошо, теперь вы (создав статичность defaultRegion'), правильно сохраняя 'defaultRegion'. Следующая проблема заключается в том, что вы устанавливаете 'defaultRegion' сразу после создания' MKMapView', но процесс установки области для покрытия США происходит асинхронно. См. Мой обновленный ответ. – Rob

+0

@ChrisPrince Я добавил код для сохранения 'defaultRegion'. – Rob

Смежные вопросы