iOS. Приемы программирования Нахавандипур Вандад

Необходимо указать пользователю конкретное место на карте.

Решение

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

1. Создайте новый класс и назовите его MyAnnotation.

2. Убедитесь, что этот класс соответствует протоколу MKAnnotation.

3. Определите свойство типа CLLocationCoordinate2D для этого класса и назовите данное свойство coordinate. Убедитесь, что задали это свойство как readonly (только для чтения), поскольку свойство coordinate в соответствии с протоколом MKAnnotation определяется как readonly.

4. Далее можно (но не обязательно) определить два свойства типа NSString, а именно h2 и subh2, которые могут содержать заголовок и подзаголовок вашего аннотирующего вида. Оба этих свойства также будут readonly.

5. Создайте для вашего класса метод-инициализатор. Этот метод будет принимать параметр типа CLLocationCoordinate2D. В этом методе присвойте переданный параметр местоположения тому свойству, которое мы определили на этапе 3. Поскольку это свойство является readonly, его невозможно присвоить с помощью кода вне области видимости данного класса. Следовательно, инициализатор этого класса действует здесь как перемычка и позволяет опосредованно присваивать значение этому свойству. Такие же операции мы осуществим со свойствами h2 и subh2.

6. Инстанцируйте класс MyAnnotation и добавьте его к вашей карте с помощью метода addAnnotation:, относящегося к классу MKMapView.

Обсуждение

Как было рассказано в подразделе «Решение» данного раздела, нам следует создать объект, соответствующий протоколу MKAnnotation, а позже инстанцировать этот объект и передать ему карту для отображения. h-файл этого объекта будет записываться так:

#import <Foundation/Foundation.h>

#import <MapKit/MapKit.h>

@interface MyAnnotation: NSObject <MKAnnotation>

@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

@property (nonatomic, copy, readonly) NSString *h2;

@property (nonatomic, copy, readonly) NSString *subh2;

— (instancetype)initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates

h2:(NSString *)paramTitle

subTitle:(NSString *)paramSubTitle;

@end

В.m-файле класса MyAnnotation мы создаем класс, отвечающий за отображение геолокационной информации, и делаем это следующим образом:

#import «MyAnnotation.h»

@implementation MyAnnotation

— (instancetype)initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates

h2:(NSString *)paramTitle

subTitle:(NSString *)paramSubTitle{

self = [super init];

if (self!= nil){

coordinate = paramCoordinates;

h2 = paramTitle;

subh2 = paramSubTitle;

}

return(self);

}

@end

Позже мы инстанцируем этот класс и добавим его к нашей карте, например к. m-файлу того контроллера вида, который создает и отображает картографический вид:

#import «ViewController.h»

#import «MyAnnotation.h»

#import <MapKit/MapKit.h>

@interface ViewController () <MKMapViewDelegate>

@property (nonatomic, strong) MKMapView *myMapView;

@end

@implementation ViewController

— (void)viewDidLoad {

[super viewDidLoad];

/* Создаем карту такого же размера, как и наш вид. */

self.myMapView = [[MKMapView alloc]

initWithFrame: self.view.bounds];

self.myMapView.delegate = self;

/* Задаем для карты тип Standard. */

self.myMapView.mapType = MKMapTypeStandard;

self.myMapView.autoresizingMask =

UIViewAutoresizingFlexibleWidth |

UIViewAutoresizingFlexibleHeight;

/* Добавляем ее к нашему виду. */

[self.view addSubview: self.myMapView];

/* Это просто один образец местоположения. */

CLLocationCoordinate2D location =

CLLocationCoordinate2DMake(50.8219 16929 07181, -0.13 81176 71012 87842);

/* Создаем аннотацию, используя информацию о местоположении. */

MyAnnotation *annotation =

[[MyAnnotation alloc] initWithCoordinates: location

h2:@"My Title"

subTitle:@"My Sub Title"];

/* И наконец, добавляем аннотацию на карту. */

[self.myMapView addAnnotation: annotation];

@end

На рис. 9.2 показан вывод данной программы в симуляторе iPhone.

Рис. 9.2. Интегрированный в систему стандартный маркер, отображенный на карте

9.5. Отображение разноцветных маркеров в картографическом виде

Постановка задачи

По умолчанию маркеры-индикаторы, которыми отмечаются точки на карте, — красного цвета. Необходимо отображать маркеры различных цветов, а не только стандартного красного.

Решение

Возвращайте вашему картографическому виду экземпляры MKPinAnnotationView. Это делается с помощью метода делегата mapView: viewForAnnotation:.

Каждая аннотация, добавляемая к экземпляру MKMapView, соответствует конкретному виду, который отображается поверх картографического вида. Такие всплывающие виды называются аннотирующими (Annotation Views).

Аннотирующий вид — это объект типа MKAnnotationView, он является подклассом от UIView. Если объект делегата картографического вида реализует метод делегата mapView: viewForAnnotation:, то объект делегата должен будет возвращать экземпляры класса MKAnnotationView, чтобы отображать (а при необходимости — настраивать) аннотирующие виды, которые выводятся поверх картографического вида.

Обсуждение

Чтобы обеспечить в нашей программе возможность настройки цвета меток (цвет будем выбирать из стандартной палитры, предусмотренной для меток в SDK), которые ставятся на картографическом виде для представления аннотаций, нам понадобится возвращать в методе делегата mapView: viewForAnnotation: не экземпляр класса MKAnnotationView, а экземпляр класса MKPinAnnotationView. Не забывайте, что класс MKPinAnnotationView является подклассом MKAnnotationView.

— (MKAnnotationView *)mapView:(MKMapView *)mapView

viewForAnnotation:(id <MKAnnotation>)annotation{

MKAnnotationView *result = nil;

if ([annotation isKindOfClass: [MyAnnotation class]] == NO){

return result;

}

if ([mapView isEqual: self.myMapView] == NO){

/* Мы собираемся обработать это событие только для того Map View,

который создали ранее. */

return result;

}

/* Сначала приводим тип той аннотации, для которой этот Map View

запустил данное сообщение делегата. */

MyAnnotation *senderAnnotation = (MyAnnotation *)annotation;

/* С помощью метода класса, определенного нами в собственном

классе аннотаций, мы попытаемся сделать многоразовый идентификатор

для того маркера, который сейчас создаем. */

NSString *pinReusableIdentifier =

[MyAnnotation

reusableIdentifierforPinColor: senderAnnotation.pinColor];

/* Пользуясь идентификатором, полученным ранее, попытаемся

повторно применить маркер в отправляющем Map View. */

MKPinAnnotationView *annotationView = (MKPinAnnotationView *)

[mapView

dequeueReusableAnnotationViewWithIdentifier: pinReusableIdentifier];

if (annotationView == nil){

/* Если нам не удастся повторно использовать имеющийся маркер,

создадим новый. */

annotationView = [[MKPinAnnotationView alloc]

initWithAnnotation: senderAnnotation

reuseIdentifier: pinReusableIdentifier];

/* Убеждаемся, что видны выноски поверх каждого маркера в случае,

если мы присвоили каждому маркеру заголовок и/или подзаголовок. */

[annotationView setCanShowCallout: YES];

}

/* Теперь (независимо от того, использовали мы многоразовый маркер

или создали новый) убеждаемся, что цвет маркера совпадает с цветом

аннотации. */

annotationView.pinColor = senderAnnotation.pinColor;

result = annotationView;

return result;

}

При многократном использовании аннотирующего вида ему присваивается идентификатор (строка NSString). Определяя, маркер какого типа вы хотели бы отобразить на карте, и задавая уникальный идентификатор для маркера каждого типа (например, к одному типу могут относиться красные маркеры, а к другому — синие), следует многократно использовать маркеры нужного типа, применяя метод экземпляра dequeueReusableAnnotationViewWithIdentifier:, относящийся к классу MKMapView. Это показано в следующем коде.

Мы запрограммировали механизм получения уникальных идентификаторов каждого маркера в собственном классе MyAnnotation. Вот. h-файл класса MyAnnotation:

#import <Foundation/Foundation.h>

#import <MapKit/MapKit.h>

/* Это стандартные цвета меток, присутствующие в SDK. Мы задаем уникальные

идентификаторы для каждого маркера в соответствии с его цветом, чтобы

позже можно было снова использовать созданные ранее маркеры в связи

с тем же цветом, для которого они создавались. */

extern NSString *const kReusablePinRed;

extern NSString *const kReusablePinGreen;

extern NSString *const kReusablePinPurple;

@interface MyAnnotation: NSObject <MKAnnotation>

/* unsafe_unretained, так как это не объект. Этот шаг можно пропустить

и оставить принятие этого решения компилятору. weak или strong

не сработают, так как это не объект. */

@property (nonatomic, unsafe_unretained, readonly)

CLLocationCoordinate2D coordinate;

@property (nonatomic, copy) NSString *h2;

@property (nonatomic, copy) NSString *subh2;

/* unsafe_unretained по той же причине, что и для свойства coordinate */

@property (nonatomic, unsafe_unretained) MKPinAnnotationColor pinColor;

— (instancetype)initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates

h2:(NSString*)paramTitle

subTitle:(NSString*)paramSubTitle;

+ (NSString *) reusableIdentifierforPinColor

:(MKPinAnnotationColor)paramColor;

@end

Аннотация не то же самое, что аннотирующий вид. Аннотация — это место, которое вы хотите указать на карте, а аннотирующий вид — это визуальное представление, в котором эта аннотация всплывает над картой (то есть вид). Класс MyAnnotation соответствует аннотации, а не аннотирующему виду. Когда мы создаем аннотацию путем инстанцирования класса MyAnnotation, мы можем присвоить ей цвет, задействовав определенное и реализованное нами же свойство pinColor. Когда картографический вид должен будет отобразить аннотацию, картографический вид вызовет метод делегата mapView: viewForAnnotation: и запросит у этого делегата аннотирующий вид. В параметре forAnnotation данного метода сообщается аннотация, которую необходимо отобразить. Получая ссылку на аннотацию, мы можем привести тип аннотации к экземпляру MyAnnotation, получить ее свойство pinColor и, основываясь на этих данных, создать экземпляр класса MKPinAnnotationView. У этого экземпляра будет информация о заданном цвете маркера, которую мы вернем картографическому виду.

Вот. m-файл MyAnnotation:

#import «MyAnnotation.h»

NSString *const kReusablePinRed = @"Red";

NSString *const kReusablePinGreen = @"Green";

NSString *const kReusablePinPurple = @"Purple";

@implementation MyAnnotation

+ (NSString *) reusableIdentifierforPinColor

:(MKPinAnnotationColor)paramColor{

NSString *result = nil;

switch (paramColor){

case MKPinAnnotationColorRed:{

result = REUSABLE_PIN_RED;

break;

}

case MKPinAnnotationColorGreen:{

result = REUSABLE_PIN_GREEN;

break;

}

case MKPinAnnotationColorPurple:{

result = REUSABLE_PIN_PURPLE;

break;

}

}

return result;

}

— (instancetype)initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates

h2:(NSString*)paramTitle

subTitle:(NSString*)paramSubTitle{

self = [super init];

if (self!= nil){

_coordinate = paramCoordinates;

_h2 = paramTitle;

_subh2 = paramSubTitle;

_pinColor = MKPinAnnotationColorGreen;

}

return self;

}

@end

Выполнив реализацию класса MyAnnotation, его нужно задействовать в приложении (в данном примере мы воспользуемся контроллером вида). Вот верхняя часть файла реализации контроллера вида:

#import «ViewController.h»

#import «MyAnnotation.h»

#import <MapKit/MapKit.h>

@interface ViewController () <MKMapViewDelegate>

@property (nonatomic, strong) MKMapView *myMapView;

@end

@implementation ViewControllerРеализация в файле. m будет такой:

— (MKAnnotationView *)mapView:(MKMapView *)mapView

viewForAnnotation:(id <MKAnnotation>)annotation{

MKAnnotationView *result = nil;

if ([annotation isKindOfClass: [MyAnnotation class]] == NO){

return result;

Страницы: «« ... 3940414243444546 ... »»

Читать бесплатно другие книги:

Рассмотрены основы информатики и описаны современные аппаратные средства персонального компьютера. С...
Молодые парни из экстремистской организации «Русский трибунал» объявили партизанскую войну «предател...
Покончив с несчастливым браком, Грейс решила, что больше никогда не доверится мужчине и не поставит ...
Лиз Сазерленд только мечтала о том, чтобы черная полоса ее жизни когда-нибудь сменилась белой. Пробл...
В старину ставили храмы на полях сражений в память о героях и мучениках, отдавших за Родину жизнь. Н...
В учебном пособии представлены вариативные авторские методики воспитания и развития волевых качеств ...