ПРОГРАММИРОВАНИЕ ПОД IPHONE, IPAD OBJECTIVE-C часть 3

Детальней о метках

В предыдущем примере мы научились добавлять на карту метки. Но это была лишь поверхносная информация о работе с метками. Не учтено множество возможностей. К примеру, мы рассматривали возможность задать метке другой цвет. Но наш выбор цветов ограничен и не было сказано ни слова как применить свою картинку. Как раз с этого я решил начать пример.

 

Чтобы не создавать новый проект скачайте исходный код примера Добавление меток на карту (MKAnnotation) и добавьте в него две картинки, которые которые можно скачать здесь.

 

В прошлый раз мы добавляли на карту метки с помощью класса MKPinAnnotationView. Это было легко и просто, тем более, можно использовать анимацию добавления. Но если вы хотите установить метке свою картинку — следует использовать класс MKAnnotationView. Он не имеет стандартного метод animatesDrop, то есть, реализацию анимации для такой метки вам прийдется писать самим. Но этот пример не о том. Изменим метод viewForAnnotation с учетом всего вышенаписаного:

 

<code data-result="[object Object]">- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id &lt;MKAnnotation&gt;)annotation 
{   
    if (annotation == mapView.userLocation) {
        return nil;
    }

    if ([[annotation title] isEqualToString:@"Custom"]) {
        static NSString* customAnnotationIdentifier = @"customAnnotationIdentifier";
        MKAnnotationView* annotationView = (MKAnnotationView *)[mapView 
                                                                dequeueReusableAnnotationViewWithIdentifier:
                                                                customAnnotationIdentifier];

        if (!annotationView) {
            annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation 
                                                           reuseIdentifier:nil] autorelease];
            annotationView.image = [UIImage imageNamed:@"flag.png"];
            return annotationView;
        }

        return annotationView;
    } else {
        static NSString* annotationIdentifier = @"annotationIdentifier";
        MKPinAnnotationView* annotationView = (MKPinAnnotationView *)[mapView 
                                                                      dequeueReusableAnnotationViewWithIdentifier:
                                                                      annotationIdentifier];

        if (!annotationView) {
            annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation 
                                                              reuseIdentifier:nil] autorelease];

            if([[annotation title] isEqualToString:@"Annotation1"]) {
                [annotationView setPinColor:MKPinAnnotationColorRed];
            } else {
                [annotationView setPinColor:MKPinAnnotationColorGreen];
                annotationView.animatesDrop = YES;
                annotationView.canShowCallout = YES;
            }
        }

        return annotationView;
    }
}</code>

 

Все работает так же, как с обычными меткам, но как я уже говорил, используем мы класс MKAnnotationView, а он имеет одно полезное свойство image, которому мы устанавливаем нужную картинку. Осталось лишь добавить на карту метку с надписью «Custom». Сделаем мы это в методе viewDidLoad, добавив в него следующий код:

 

<code data-result="[object Object]">Annotation *annotation3 = [Annotation new];
annotation3.title = @"Custom";
annotation3.subtitle = @"My custom annotation";
annotation3.coordinate = CLLocationCoordinate2DMake(48.498674f, 36.895776f);
[map addAnnotation:annotation3];
[annotation3 release];</code>

 

При запуске приложениея на карту будет добавлена метка с тем изображением, которое мы указали.

 

Теперь обратим внимание на сноски, которые отображаются при нажатии на метку. Сноска есть как у MKPinAnnotationView так и MKAnnotationView. Как было сказано в прошлом примере, для отображения сноски, свойству метки canShowCallout следует установить значение YES. При этом, у метки есть еще два полезных свойства:

 

  • leftCalloutAccessoryView
  • rightCalloutAccessoryView

 

Этим свойствам можно установить любой объект типа UIView или его наследника. Изменим метод viewForAnnotation с использованием вышеупомянутых свойств:

 

<code data-result="[object Object]">- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id &lt;MKAnnotation&gt;)annotation 
{   
    if (annotation == mapView.userLocation) {
        return nil;
    }

    if ([[annotation title] isEqualToString:@"Custom"]) {
        static NSString* customAnnotationIdentifier = @"customAnnotationIdentifier";
        MKAnnotationView* annotationView = (MKAnnotationView *)[mapView 
                                                                dequeueReusableAnnotationViewWithIdentifier:
                                                                customAnnotationIdentifier];

        if (!annotationView) {
            annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation 
                                                           reuseIdentifier:nil] autorelease];
            annotationView.image = [UIImage imageNamed:@"flag.png"];

            annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
            annotationView.canShowCallout = YES;
            UIImageView *sfIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SFIcon.png"]];
            annotationView.leftCalloutAccessoryView = sfIconView;
            [sfIconView release];

            return annotationView;
        }

        return annotationView;
    } else {
        static NSString* annotationIdentifier = @"annotationIdentifier";
        MKPinAnnotationView* annotationView = (MKPinAnnotationView *)[mapView 
                                                                      dequeueReusableAnnotationViewWithIdentifier:
                                                                      annotationIdentifier];

        if (!annotationView) {
            annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation 
                                                              reuseIdentifier:nil] autorelease];

            if([[annotation title] isEqualToString:@"Annotation1"]) {
                [annotationView setPinColor:MKPinAnnotationColorRed];
            } else {
                [annotationView setPinColor:MKPinAnnotationColorGreen];
                annotationView.animatesDrop = YES;
                annotationView.canShowCallout = YES;
                annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
            }
        }

        return annotationView;
    }
}</code>

 

Теперь каждая сноска будет иметь кнопку с правой стороны, а сноска кастомной метки еще и картинку с левой стороны.

 

Для обработки нажатия на эти сноски следует использовать метод calloutAccessoryControlTapped, но здесь я хочу сделать маленькое отступление. Для чистоты эксперемента я предлагаю при нажатии на эту самую кнопку переходить на детальное описание того места, которое отмечено на карте. Но если вы знакомы с предыдущими примерами на этом сайте — то должны понимать, что сейчас нам прийдется добавить в проект контроллер навигации и еще один контроллер представления. Для тех, кто не знает о чем идет речь, рекомендую прочитать примеры по использованию UINavigationController.

 

<code data-result="[object Object]">- (void)mapView:(MKMapView *)mapView 
 annotationView:(MKAnnotationView *)view 
calloutAccessoryControlTapped:(UIControl *)control 
{
    Annotation *annotationTapped = (Annotation *)view.annotation;

    DetailViewController *detail = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
    detail.title = annotationTapped.title;
    [self.navigationController pushViewController:detail animated:YES];
    [detail release];
}</code>

 

Как видно с кода, свой контроллер представления я назвал DetailViewController, а в момент нажатия на кнопку сноски будет получена ее метка, и название метки передано свойству title нашего контроллера.

 

Исходный код этого проекта можно скачать здесь.

Comments are closed.