繁体   English   中英

在MKMapView上自定义一个注释

[英]Custom one annotation on 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;
}

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

我希望我很清楚

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

@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的错误对象返回到关联的完成处理程序。)以下是有效使用此类的一些经验法则:

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM