iOS mapView有时无法加载到默认位置

时间:2012-10-11 21:03:23

标签: ios location mkmapview grand-central-dispatch mkcoordinateregion

每次访问视图时,我都会将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 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,以下解决方案(适用于您的代码)对我有用:

-(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

答案 1 :(得分:0)

您正在更新不同于主队列的队列上的地图。你很幸运,你的应用程序并没有崩溃到处。将视图操作移动到主线程,看看是否继续遇到同样的问题。

编辑:如果你真的必须使用队列来获得该范围,只需使用视图执行此操作:

dispatch_async(dispatch_get_main_queue(), ^{
    [mapView setRegion:region animated:YES]; 
});

答案 2 :(得分:0)

上面的代码中只有一个点可以将地图设置为地图位置(setRegion)。如果您的地图设置为其他位置,则不在您提供的代码中。