0

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

问题是当我在视图中的 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];
}

感谢您的帮助,谢谢。抱歉,如果这是草率,这是我的第一篇文章。

编辑:
这是我根据 nevan king 的回答编辑的地理编码器方法。

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

也不是我尝试使用注释数组的计数来确定最后一个注释的地理编码完成处理程序以仅更改该特定区域的区域。但这对我所在的地区产生了不一致的结果。这是它始终将所有注释保持在视图中的唯一方法。

4

3 回答 3

2

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

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

于 2013-07-11T23:24:15.990 回答
0

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

于 2013-07-11T23:18:08.267 回答
0

在所有注释都经过地理编码并加载到地图上之后,运行方法的最佳方法似乎是运行一个简单的计数和一个 if 语句,用数组计数检查计数。

这是我想出的: int pointsArrayCount = contactArray.count; NSLog(@"Count : %d", pointsArrayCount); int numberOfPoints = pointsArrayCount; NSLog(@"Count Number : %d", numberOfPoints); 我 = 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 个地理编码。因此,这仅在您在地理编码时向地图加载少量数据时才有效。如果您做的不止这些,那么您应该将所有坐标存储在某处,然后在地图加载时单独加载它们。

于 2013-07-17T21:18:13.337 回答