在MKMapView上自定义一个注释

时间:2015-05-12 07:29:02

标签: ios objective-c mkmapview

我用MKPLaceMark填充我的地图,其中包含特定地址,这些标记对应于会议。

我正在尝试自定义与下次会议相对应的一个地标。

这是我的代码:

// Function to add all pin corresponding to all meeting.
- (void) addAllPins {
    _myMap.delegate = self;

    // Get all key of meeting
    NSArray* allKey = [[VSDataProvider sharedManager].startEvents allKeys];

    for (NSDate *date in allKey) {
        for (FFEvent *event in [[VSDataProvider sharedManager].startEvents objectForKey:date]) {

            // Retrieve with CLGeocoder the latitude and longitude with address of event
            NSString *localisation = [NSString stringWithFormat:@"%@ %@ %@ %@",event.street,event.zipCode,event.city,event.country];

            CLGeocoder *geocoder = [[CLGeocoder alloc] init];
            [geocoder geocodeAddressString:localisation completionHandler:^(NSArray *placemarks, NSError *error) {
                if (placemarks && placemarks.count > 0) {
                    CLPlacemark *topResult = [placemarks objectAtIndex:0];
                    MKPlacemark *place = [[MKPlacemark alloc] initWithPlacemark:topResult];
                    [arrayWithAllLocation addObject:place];
                    [self addPinWithTitle:event.street AndCoordinateLongitude:place.coordinate.longitude AndCoordinateLatitude:place.coordinate.latitude];
                }

                [self getCoordinateNexEvent:^{
                    for (MKPlacemark *mark in arrayWithAllLocation) {
                        if (mark.coordinate.latitude ==  _coordinateNextEvent.latitude && mark.coordinate.longitude == _coordinateNextEvent.longitude) {
                            MKAnnotationView *test = [[MKAnnotationView alloc]initWithAnnotation:mark reuseIdentifier:@"nextEvent"];
                            test.annotation = mark;
                            test.image = [UIImage imageNamed:@"Meeting.png"];
                            [_myMap addAnnotation:test.annotation]; 
                        }
                    }
                }];
            }];
        }
    }
}

// Retrieve coordinate for the next meeting
- (void) getCoordinateNexEvent :(void (^)(void))afterAll {
    FFEvent *event = [VSDataProvider sharedManager].nextEvent;
    CLGeocoder *geocoder = [[CLGeocoder alloc]init];
    NSString *localisation = [NSString stringWithFormat:@"%@ %@ %@ %@",event.street,event.zipCode,event.city,event.country];
    [geocoder geocodeAddressString:localisation completionHandler:^(NSArray *placemarks, NSError *error) {

        if (placemarks && placemarks.count > 0) {
            CLPlacemark *topResult = [placemarks objectAtIndex:0];
            placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
            _coordinateNextEvent.latitude = placemark.coordinate.latitude;
            _coordinateNextEvent.longitude = placemark.coordinate.longitude;
        }

        afterAll();
    }];
}

// This method add a Pin with the title and coordinate
- (void) addPinWithTitle : (NSString*)title AndCoordinateLongitude : (double)coordinateLongitude AndCoordinateLatitude : (double)coordinateLatitue {
    MKPointAnnotation *mapPin = [[MKPointAnnotation alloc]init];
    CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(coordinateLatitue, coordinateLongitude);
    mapPin.title = title;
    mapPin.coordinate = coordinate;
    [self.myMap addAnnotation:mapPin];
}

- (void) mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {    
    MKCoordinateRegion region;
    MKCoordinateSpan span;

    span.latitudeDelta = 0.5;
    span.longitudeDelta = 0.5;

    CLLocationCoordinate2D location;
    location.latitude = userLocation.coordinate.latitude;
    location.longitude = userLocation.coordinate.longitude;

    region.span = span;
    region.center = location;

    [_myMap setRegion:region animated:YES];
}

当我使用

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

    __block MKAnnotationView *annotationWithNextEvent;

    annotationWithNextEvent = (MKAnnotationView*) [_myMap dequeueReusableAnnotationViewWithIdentifier:@"nextEventAnnotation"];

    if (!annotationWithNextEvent) {

        annotationWithNextEvent = [[MKAnnotationView alloc] initWithAnnotation:placemark reuseIdentifier:@"nextEventAnnotation"];
    }
    annotationWithNextEvent.image = [UIImage imageNamed:@"Meeting.png"];
    annotationWithNextEvent.annotation = annotation;
    return annotationWithNextEvent;
}

所有注释都是图像,我不想要这个。

我希望我很清楚

1 个答案:

答案 0 :(得分:0)

您应该为它创建子类,如下所示:

@interface MeetingPointAnnotation : MKPointAnnotation
@property (strong, nonatomic) NSString *customData;
@end

然后检查它:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[MeetingPointAnnotation class]]) {
        __block MKAnnotationView *annotationWithNextEvent;
        annotationWithNextEvent = (MKAnnotationView*) [_myMap dequeueReusableAnnotationViewWithIdentifier:@"nextEventAnnotation"];

        if (!annotationWithNextEvent) {
            annotationWithNextEvent = [[MKAnnotationView alloc] initWithAnnotation:placemark reuseIdentifier:@"nextEventAnnotation"];
        }

        annotationWithNextEvent.image = [UIImage imageNamed:@"Meeting.png"];
        annotationWithNextEvent.annotation = annotation;
        return annotationWithNextEvent;
    }
    return nil;
}

这将仅自定义该类型的注释

此外,您的代码可能与CLGeocoder存在问题,因为它可能会大量使用它。请阅读文档:

  

应用程序应该意识到它们如何使用地理编码。地理编码请求对每个应用程序都是速率限制的,因此在短时间内发出过多请求可能会导致某些请求失败。 (当超过最大速率时,地理编码器会将值为kCLErrorNetwork的错误对象返回到关联的完成处理程序。)以下是有效使用此类的一些经验法则:

     
      
  • 为任何一个用户操作发送最多一个地理编码请求。

  •   
  • 如果用户执行涉及对同一位置进行地理编码的多个操作,请重复使用初始地理编码请求中的结果,而不是针对每个操作启动单个请求。

  •   
  • 如果要自动更新用户的当前位置(例如用户移动时),请仅在用户移动了很长的距离并经过一段合理的时间后才发出新的地理编码请求。例如,在典型情况下,您不应每分钟发送多个地理编码请求。

  •   
  • 当用户不立即看到结果时,请勿启动地理编码请求。例如,如果您的应用程序处于非活动状态或在后台运行,请不要启动请求。

  •