iOS mapView иногда не загружается в положение по умолчанию

Мой mapView установлен в местоположение по умолчанию каждый раз, когда к нему обращаются. Иногда, когда вы получаете доступ к представлению, оно будет в правильном месте, хотя иногда, когда вы получаете доступ к представлению, оно будет в местоположении по умолчанию на карте, над океаном к югу от Африки. Как я могу убедиться, что он находится в правильном месте при доступе к представлению.

Вот мой код:

-(void)viewDidLoad {

    [super viewDidLoad];

    self.mapView.delegate = self;

    MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
    region.center.latitude = 45.442424;
    region.center.longitude = -122.78;
    region.span.latitudeDelta =  0.60;
    region.span.longitudeDelta =  0.60;
    [mapView setRegion:region animated:YES];
}

Вот что загружает аннотации:

-(void)initXML {

    NSURL *theURL = [NSURL URLWithString:@"http://www.wccca.com/PITS/"];
    NSData *data = [[NSData alloc] initWithContentsOfURL:theURL];
    xpathParser = [[TFHpple alloc] initWithHTMLData:data];
    NSArray *elements = [xpathParser searchWithXPathQuery:@"//input[@id='hidXMLID']//@value"];
    if (elements.count >= 1) {

        TFHppleElement *element = [elements objectAtIndex:0];
        TFHppleElement *child = [element.children objectAtIndex:0];
        NSString *idValue = [child content];

        NSString *idwithxml = [idValue stringByAppendingFormat:@".xml"];
        NSString *url = @"http://www.wccca.com/PITS/xml/fire_data_";
        NSString *finalurl = [url stringByAppendingString:idwithxml];

        xmlParser = [[XMLParser alloc] loadXMLByURL:finalurl];

        if (xmlParser.calls.count == 0) {

            [self noCallsMessage];
        }
        else {

            [self wcccaAnn];

            NSArray *callsArray = [xmlParser calls];

            for (JointCAD *call in callsArray) {
                NSString *callnumber = [call.callnumber stringByAppendingFormat:@". "];
                NSString *callandnumber = [callnumber stringByAppendingString:call.currentCallType];
                Annotation *ann = [[Annotation alloc] init];
                ann.title = callandnumber;
                ann.subtitle = [call location];
                ann.coordinate = CLLocationCoordinate2DMake([call.latitude doubleValue], [call.longitude doubleValue]);
                [mapView addAnnotation:ann]; }
            }
        }
    }

MKAnnotationView:

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {

    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    MKPinAnnotationView *MyPin=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"current"];
    MyPin.pinColor = MKPinAnnotationColorRed;

    MyPin.draggable = NO;
    MyPin.highlighted = YES;
    MyPin.animatesDrop= YES;
    MyPin.canShowCallout = YES;

    return MyPin;
}

3 ответа

У меня была такая же проблема, и у меня сработало следующее решение (примененное к вашему коду):

-(void)viewDidLoad {

    [super viewDidLoad];

    self.mapView.delegate = self;

    double delayInSeconds = 0.5;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
        region.center.latitude = 45.442424;
        region.center.longitude = -122.78;
        region.span.latitudeDelta =  0.60;
        region.span.longitudeDelta =  0.60;
        [mapView setRegion:region animated:YES];
    });
}

По сути, вы оборачиваете код, который устанавливает область в блок, и вызываете этот блок после delayInSeconds, Я нашел 0,5 достаточно задержки в симуляторе, но вы должны проверить на своем медленном устройстве.

Если вы не хотите использовать блоки, вы можете также обернуть код установки региона в отдельный метод и вызвать что-то вроде [self performSelector:@selector(nameOfMethod) withObject:nil afterDelay:0.5f];,

Карта начнет загружаться, а затем быстро анимируется в заданном регионе. Если вам не нравится эта анимация, то обязательно установите animated параметр для NO,

В приведенном выше коде есть только одна точка, которая устанавливает карты на карте (setRegion). Если ваша карта находится в другом месте, она не указана в предоставленном вами коде.

Вы обновляете карту в очереди, отличной от основной очереди. Вам повезло, что ваше приложение не падает везде. Переместите манипуляции с представлениями в основной поток и посмотрите, продолжаете ли вы получать ту же проблему.

изменить: если вам действительно нужно использовать очередь, чтобы получить этот промежуток, просто сделайте это с представлением:

dispatch_async(dispatch_get_main_queue(), ^{
    [mapView setRegion:region animated:YES]; 
});
Другие вопросы по тегам