在iPhone中,我如何知道在使用前向地理编码时何时加载了所有地图的注释?

问题描述:

在我的应用程序中,我有一个表视图,用于切换地图视图上的注释。我可以通过标签栏控制器在表格视图和地图视图之间来回切换。我的地图将重新加载视图确实出现的注释(来自表格视图中选定的项目)。我需要知道何时加载这些注释,以便我可以运行缩放到由注释群集确定的生成区域的方法。在iPhone中,我如何知道在使用前向地理编码时何时加载了所有地图的注释?

问题是当我在视图中的addAnnotations方法出现后直接运行缩放方法时,它会在我的注释获得正确的坐标之前开始缩放过程。从而导致缩放不正确,我的注释移动到正确的位置。

我还想指出,我正在使用向前地理编码来获取我的注释坐标。

这是我的看法没有出现:

[super viewDidAppear:animated]; 

[businessMap removeAnnotations:businessPoints]; 
[businessPoints removeAllObjects]; 

UINavigationController *navVC = (UINavigationController *) [self.tabBarController.viewControllers objectAtIndex:0]; 

FirstViewController *VC = [navVC.viewControllers objectAtIndex:0]; 

for (businessInfo *business_info in VC.selectedBusinessesArray) { 



    businessInfoAnnotation *businessAnnotation = [[businessInfoAnnotation alloc] init]; 

    businessAnnotation.businessInfoClass = business_info; 

    CLGeocoder *geocoder = [[CLGeocoder alloc] init]; 

    [geocoder geocodeAddressString:business_info.location 
       completionHandler:^(NSArray* geocoded, NSError* error){ 
        if (geocoded && geocoded.count > 0) { 
         CLPlacemark *placemark = [geocoded objectAtIndex:0]; 
         CLLocation *location = placemark.location; 
         CLLocationCoordinate2D business_cords = location.coordinate; 
         businessAnnotation.coordinate = business_cords; 
        } 
       }]; 

    businessAnnotation.title = business_info.name; 

    [businessPoints addObject:businessAnnotation]; 

} 

[businessMap addAnnotations:businessPoints]; 

[businessMap setZoomEnabled:YES]; 

[self zoomToFitMapAnnotations:businessMap withArray:businessPoints]; 

这里是我的变焦方法:

-(void)zoomToFitMapAnnotations:(MKMapView*)mapViews withArray:(NSArray*)anAnnotationArray 
{ 
    if([mapViews.annotations count] == 0) return; 

    CLLocationCoordinate2D topLeftCoord; 
    topLeftCoord.latitude = -90; 
    topLeftCoord.longitude = 180; 
    NSLog(@"zooming"); 

    CLLocationCoordinate2D bottomRightCoord; 
    bottomRightCoord.latitude = 90; 
    bottomRightCoord.longitude = -180; 



    for(MKPointAnnotation* annotation in anAnnotationArray) 
    { 
     topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude); 
     topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude); 

     bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude); 
     bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude); 
    } 

    MKCoordinateRegion region; 
    region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5; 
    region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5; 
    region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1; 
    region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; 

    region = [mapViews regionThatFits:region]; 
    [businessMap setRegion:region animated:YES]; 
} 

您的帮助表示赞赏,感谢。对不起,如果这是马虎,这是我的第一篇文章。

编辑:
下面是根据妮娃王的答案我编辑的地理编码方法。

[geocoder geocodeAddressString:business_info.location 
      completionHandler:^(NSArray* geocoded, NSError* error){ 
       if (geocoded && geocoded.count > 0) { 
        CLPlacemark *placemark = [geocoded objectAtIndex:0]; 
        CLLocation *location = placemark.location; 
        CLLocationCoordinate2D business_cords = location.coordinate; 
        businessAnnotation.coordinate = business_cords; 

        businessAnnotation.title = business_info.name; 

        [businessPoints addObject:businessAnnotation]; 

        [businessMap addAnnotations:businessPoints]; 

        [self zoomToFitMapAnnotations:businessMap withArray:businessPoints]; 
       } 
      } 
]; 

也没有,我试图使用注释阵列的数量,以确定最后的注释的地理编码completionHandler改变只在特定的地区之一。但是这给我的地区带来了不一致的结果。这是始终如一地保留所有注释的唯一方式。

在所有注解被地理编码并加载到地图上后,运行方法似乎是运行简单计数和if语句来检查计数数量的最佳方式。

这是我想出来的: int pointsArrayCount = contactArray。计数; NSLog(@“Count:%d”,pointsArrayCount); int numberOfPoints = pointsArrayCount; NSLog(@“Count Number:%d”,numberOfPoints); i = 0;

for (contactInfo *contact_info in contactArray) { 

    contatcInfoAnnotation *annotation = [[contatcInfoAnnotation alloc] init]; 

    annotation.contactInfoClass = contact_info; 

    CLGeocoder *geocoder = [[CLGeocoder alloc] init]; 

    [geocoder geocodeAddressString:contact_info.address 
       completionHandler:^(NSArray* geocoded, NSError* error){ 
        if (geocoded && geocoded.count > 0) { 
         CLPlacemark *placemark = [geocoded objectAtIndex:0]; 
         CLLocation *location = placemark.location; 
         CLLocationCoordinate2D contact_cords = location.coordinate; 
         annotation.coordinate = contact_cords; 

         annotation.title = contact_info.name; 

         [mapPoints addObject:annotation]; 

         [mapView addAnnotations:mapPoints]; 

         i++; 

         NSLog(@"Count Number of Geocoded: %d", i); 

         if(i == numberOfPoints) { 
          [self zoomToFitMapAnnotations:mapView withArray:mapPoints]; 
         } 
        } 
       }//end completionHandler 
    ]; 

但是,完成处理程序最多只能处理40个地理编码。所以这只有在地理编码时加载少量地图到你的地图时才有效。如果你做的不止这些,那么你应该将所有坐标存储在某个地方,然后在地图加载时单独加载它们。

您可以使用一个调度组,但我相信您必须手动使用dispatch_group_enter和dispatch_group_leave,而不是dispatch_group_async。这样,您可以在每次调用geocodeAddressString之前输入组,并在完成块完成时离开组。完成所有完成块后,dispatch_notify将调用您的代码进行调整大小。

MKMapViewDelegate有一个mapView:didAddAnnotationViews:方法,它在一组注释视图被放置在地图上之后调用。请注意,它与注释不同(某些注释根据缩放可能不可见)。

编辑:我刚刚注意到您首先对位置进行地理编码。在这种情况下,您必须将注释添加到地理编码完成处理程序中的地图中。在主线上做。在您的代码中,当您拨打addAnnotations:时,完成功能块尚未完成。