Одним из самых востребованных и удобных инструментов для разработчика на платформе iOS являются интегрированные карты (класс  MKMapView). Как известно этот класс отображает карту на экране iPhone, текущее местоположение пользователя, «булавки» и прочие полезные вещи. Можно предположить ситуацию, когда в приложении мы предоставляем пользователю разнообразную информацию на карте. Например, у нас есть приложение, в котором создана огромная база данных по различным магазинам города. Всем пользователям нравится, все довольны. Однако со временем информация устаревает: магазины закрываются или переезжают на новое место. Самостоятельно поддерживать актуальную базу достаточно сложно. В такой ситуации необходимо дать инструмент, с помощью которого пользователи смогут самостоятельно указать новое место магазина на карте или удалить отметку совсем. Рассмотрим вариант, когда пользователь может самостоятельно указать новое место на карте. Все что ему необходимо сделать — это перетащить булавку на новое место. Просто, не так ли!?

Теперь переходим непосредственно к программной части. Предположим нам необходимо вывести на экран одну «булавку», которая будет отображать на карте объект с известными нам координатами. В-первую очередь создадим класс, который будет это самой «булавкой». Заголовочный файл уместится всего в несколько строк:

@interface MapAnnotation

: NSObject<mkannotation> {
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;
}
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString* title;
@property (nonatomic, copy) NSString* subtitle;
-(id)initWithCoordinate:(CLLocationCoordinate2D) c;
@end

Как мы видим у нашего класса есть три параметра: координаты, заголовок, и подзаголовок. Заголовок будем использовать для отображения названия объекта, а подзаголовок для отображения его адреса на карте. Также есть метод инициализации, с помощью которого мы устанавливаем координаты. Файл имплементации еще более короткий: все что мы делаем это устанавливаем координаты.

#import "MapAnnotation.h"

@implementation MapAnnotation
@synthesize title, subtitle, coordinate;
-(id)initWithCoordinate:(CLLocationCoordinate2D) c {
self = [super init];
coordinate=c;
return self;
}
-(void) dealloc {
self.title = nil;
self.subtitle = nil;
[super dealloc];
}
@end

Теперь перейдем к форме, которая будет отображать карту и наш объект. Создадим новый класс UIViewController и добавим на него класс MKMapView,  и протокол MKMapViewDelegate.

@interface MapViewController

: UIViewController <mkmapViewDelegate> {
MKMapView *map;
}
@property (nonatomic, retain) IBOutlet MKMapView *map;
@end

В файл инмплементации в метод viewDidLoad добавим следующие строки:

- (void)viewDidLoad

{
[super viewDidLoad];
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(51.1000, 61.1000);
MapAnnotation *placemark = [[MapAnnotation alloc] initWithCoordinate:coord];
placemark.title = @"Кремль";
placemark.subtitle = @"Россия, Москва";
[map addAnnotation:placemark];
[placemark release];
}

При загрузки нашего контроллера мы добавляем «булавку» на карту. Для переменной coord указаны тестовые данные, которые при необходимости можно заменить своими. Далее добавим следующие строки:

- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id<mkannotation>)annotation

{
static NSString* MyIdentifier = @"CustomAnnotation";
MKPinAnnotationView* pinView = (MKPinAnnotationView *)
[map dequeueReusableAnnotationViewWithIdentifier:MyIdentifier];
if (!pinView)
{
MKPinAnnotationView* customPinView
= [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:MyIdentifier] autorelease];
customPinView.animatesDrop = YES;
customPinView.canShowCallout = YES;
customPinView.draggable = YES;
return customPinView;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}

Этот делегат отвечает в частности за графическое отображение наших данных на карте.  Он вызывается для каждого объекта MKAnnotation, который был добавлен на карту. Мы с вами уже добавили туда один объект. Теперь нужно выставить интересующие свойства. Нас интересует строка:

customPinView.draggable = YES;

Если вы указали «YES», то пользователи легко смогут перемещать «булавку» по карте. Осталось отследить это событие. За это отвечает еще один делегат:

-(void)mapView:(MKMapView *)mapView

annotationView:(MKAnnotationView *)view
didChangeDragState:(MKAnnotationViewDragState)newState
fromOldState:(MKAnnotationViewDragState)oldState {
if (oldState == MKAnnotationViewDragStateDragging) {
}
if (newState == MKAnnotationViewDragStateEnding) {
NSString *tmp
= [NSString stringWithFormat:@"%f, %f",
view.annotation.coordinate.latitude,
view.annotation.coordinate.longitude];
UIAlertView *alertView
= [[UIAlertView alloc] initWithTitle:@"Подтвердите координаты"
message:tmp
delegate:self
cancelButtonTitle:@"Нет"
otherButtonTitles:@"Да",nil];
[alertView show];
[alertView release];
}
}

Как понятно из названия делегата, он вызывается каждый раз, когда местоположение одной из «булавок» было изменено пользователем. Здесь для примера будет выводиться сообщение с новыми координатами. Напишем делегат, который будет отрабатывать нажатия кнопок (пользователь может нажать «Да» или «Нет»):

- (void)alertView:(UIAlertView *)alertView

didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
// Пользователь нажал "Нет"
}
else if (buttonIndex == 1) {
// Пользователь нажал "Да"
// Код для изменения координат
}
}

При нажатии кнопки «Да» мы можем сделать вызов фунции, которая будет делать запись с новыми координатами в базу данных приложения или отправлять запрос на веб-сервис.

Похожие статьи

  • [Swift] Урок 1 — Пишем программу «Hello, World» на Swift языке под iOS

  • Audio Unit в iOS. Часть 3, накладываем эффект Delay

  • Audio Unit в iOS. Часть 2, строим граф и проигрываем файлы

  • Audio Unit в iOS. Часть 1, введение.

  • Используем Emoji в своих приложениях

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *