Большой перерыв получился с выполнения предыдущего урока в связи, с тем что я устроился разработчиком под IOS в крупную IT компанию.
Свободное время появилось только сейчас - в новогодние каникулы. Надеюсь пройти и закончить этот курс Алексея Скутаренко в ближайшее время. Так же планировал продолжить изучение разработки под IOS в новом курсе Алексея - Swift Development Course Beginner
Урок 37 и 38 посвящен библиотеке mapkit - картам Apple.
Видео 37 урока находится здесь.
Создается тестовый проект на базе Single View Application.
Для того, чтобы пользоваться картами - подключаем библиотеку в настройках проекта:
Linked FrameWorks and Libraries добавляем (+) MapKit.framework.
В тех классах где будем применять карты необходимо так же подключить главный загадочный файл MapKit.h (в нем подключаются все остальные заголовочные файлы фреймворка).
Создается Navigation controller и ViewController.
На ViewController помещаем MapView
Создаем аутлет MapView в заголочном файле.
Чтобы не было ошибки прописываем, что MKMapView будет объявлен (подключен) позже:
Импорт лучше переносить внутрь реализации.
В .m файле подключаем MapKit.h:
Определяем функции делегата, для отображения когда какая запускается:
При приближении / удалении срабатывает функция regionWillChangeAnimated, которая сообщает что регион изменяется.
Регион в классе MKMapView - описывается переменной
В свою очередь MKCoordinateRegion, это структура
Которая определяется центром - center и радиусом/отклонением от центра span.
Координаты центра заданы типом - CLLocationCoordinate2D, который тоже является структурой состоящей из широты и долготы в градусах:
CLLocationDegrees - псевдоним для типа double.
span имеет тип MKCoordinateSpan. Который определяется дельтой широты и долготы
Широта на экваторе - 0. На северном полюсе - 90 градусов. На южном полюсе - 90 градусов.
Долгота от 0 до 180 градусов если идти от нулевого меридиана против часовой стрелки. и 0 до - 180 если по часовой стрелке (смотря с северного полюса).
Широта горизонтальный срез. Долгота - вертикальный срез.
Создается кнопка Add - добавить аннотацию на NavigationBar:
Для того, чтобы создавать аннотацию мы унаследуем новый класс TAMapAnnotation от NSObject и укажем, что он поддерживает протокол MKAnnotation:
Добавляем обязательные и опциональные переменные содержащиеся в протоколе:
Добавим еще одну кнопку и метод обработчик для неё, который выводит все пины на экране (масштабирует и сдвигает карту для этого):
Изменим метод для перемещения пина, таким образом, чтобы после завершения перемещения пина выводилась его координаты:
Исходный текст этого урока здесь.
Продолжение в следующем уроке
Для того, чтобы выводился запрос на показ локации необходимо
Объявить переменную:
Подписать ViewController на еще один протокол CLLocationManagerDelegate:
вставить следующий код в viewDidLoad:
NSLocationWhenInUseUsageDescription с приветствием которое будет выводиться в запросе геопозиции, например: MegaMap would like to use your location.
Свободное время появилось только сейчас - в новогодние каникулы. Надеюсь пройти и закончить этот курс Алексея Скутаренко в ближайшее время. Так же планировал продолжить изучение разработки под IOS в новом курсе Алексея - Swift Development Course Beginner
Урок 37 и 38 посвящен библиотеке mapkit - картам Apple.
Видео 37 урока находится здесь.
Создается тестовый проект на базе Single View Application.
Для того, чтобы пользоваться картами - подключаем библиотеку в настройках проекта:
Linked FrameWorks and Libraries добавляем (+) MapKit.framework.
В тех классах где будем применять карты необходимо так же подключить главный загадочный файл MapKit.h (в нем подключаются все остальные заголовочные файлы фреймворка).
Создается Navigation controller и ViewController.
На ViewController помещаем MapView
Создаем аутлет MapView в заголочном файле.
Чтобы не было ошибки прописываем, что MKMapView будет объявлен (подключен) позже:
@class MKMapView;
Импорт лучше переносить внутрь реализации.
В .m файле подключаем MapKit.h:
#import <MapKit/MapKit.h>
Делаем наш ViewController делегатом MapView:
@interface ViewController () <MKMapViewDelegate>
Так же в сторибоард перетягиваем с MapView на ViewController связь и отмечаем Delegate.
#pragma mark - MKMapViewDelegate
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated{
NSLog(@"regionWillChangeAnimated");
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
NSLog(@"regionDidChangeAnimated");
}
- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView{
NSLog(@"mapViewWillStartLoadingMap");
}
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView{
NSLog(@"mapViewDidFinishLoadingMap");
}
- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error{
NSLog(@"mapViewDidFailLoadingMap");
}
- (void)mapViewWillStartRenderingMap:(MKMapView *)mapView{
NSLog(@"mapViewWillStartRenderingMap");
}
- (void)mapViewDidFinishRenderingMap:(MKMapView *)mapView fullyRendered:(BOOL)fullyRendered{
NSLog(@"mapViewDidFinishRenderingMap");
}
Регион в классе MKMapView - описывается переменной
@property (nonatomic) MKCoordinateRegion region
В свою очередь MKCoordinateRegion, это структура
typedef struct {
CLLocationCoordinate2D center;
MKCoordinateSpan span;
} MKCoordinateRegion;
Которая определяется центром - center и радиусом/отклонением от центра span.
Координаты центра заданы типом - CLLocationCoordinate2D, который тоже является структурой состоящей из широты и долготы в градусах:
typedef struct {
CLLocationDegrees latitude;
CLLocationDegrees longitude;
} CLLocationCoordinate2D;
CLLocationDegrees - псевдоним для типа double.
typedef double CLLocationDegrees;
span имеет тип MKCoordinateSpan. Который определяется дельтой широты и долготы
typedef struct {
CLLocationDegrees latitudeDelta;
CLLocationDegrees longitudeDelta;
} MKCoordinateSpan;
Широта на экваторе - 0. На северном полюсе - 90 градусов. На южном полюсе - 90 градусов.
Долгота от 0 до 180 градусов если идти от нулевого меридиана против часовой стрелки. и 0 до - 180 если по часовой стрелке (смотря с северного полюса).
Широта горизонтальный срез. Долгота - вертикальный срез.
Создается кнопка Add - добавить аннотацию на NavigationBar:
UIBarButtonItem *addButton=[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(actionAddButton:)];
self.navigationItem.rightBarButtonItem=addButton;
@interface TAMapAnnotation : NSObject <MKAnnotation>
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy, nullable) NSString *title;
@property (nonatomic, copy, nullable) NSString *subtitle;
Убираем из них свойство - readonly (это минимальное требование).
Теперь добавляем метод - обработчик нажатия кнопки Add на NavigationBar:
#pragma mark - action
-(void) actionAddButton :(UIBarButtonItem *) sender{
TAMapAnnotation *annotation=[[TAMapAnnotation alloc]init];
annotation.coordinate=self.mapView.region.center;
annotation.title=@"Test Title";
annotation.subtitle=@"SubTitle";
[self.mapView addAnnotation:annotation];
}
Для того чтобы Пин с аннотацией падали с анимацией, определим метод:
- (nullable MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
if ([annotation isKindOfClass:[MKUserLocation class]]){
return nil;
}
static NSString *strPinIdentifier=@"Annotation";
MKPinAnnotationView *pin =(MKPinAnnotationView*) [self.mapView dequeueReusableAnnotationViewWithIdentifier:strPinIdentifier];
if (!pin) {
pin=[[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:strPinIdentifier];
pin.pinTintColor=[UIColor greenColor];
pin.animatesDrop=YES;
pin.canShowCallout=YES;
pin.draggable=YES;
}
else{
pin.annotation=annotation;
}
return pin;
}
По аналогии с ячейками таблицы создаем пин.
Для того, чтобы была возможность перетаскивать пин, необходимо определить метод:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState
fromOldState:(MKAnnotationViewDragState)oldState{
}
Добавим еще одну кнопку и метод обработчик для неё, который выводит все пины на экране (масштабирует и сдвигает карту для этого):
-(void) actionShowAll :(UIBarButtonItem *) sender{
//Создается пустой прямоугольник
MKMapRect zoomRect= MKMapRectNull;
//в цикле проходим по всем аннотациям
for (id<MKAnnotation> annotation in self.mapView.annotations) {
//сохраняем координаты текущей аннотации
CLLocationCoordinate2D location =annotation.coordinate;
//переводим координаты текущей аннотации в 2д формат координат
MKMapPoint center=MKMapPointForCoordinate(location);
//определяем дельту для квадрата с аннотацией.
static double delta = 20000;
//создаем вокруг аннотации квадрат +-дельта
MKMapRect rect=MKMapRectMake(center.x-delta, center.y-delta, delta*2, delta*2);
//объединяем в один прямоугольник
zoomRect =MKMapRectUnion(zoomRect, rect);
}
//исправляем полученный прямоугольник для вывода его на экран
zoomRect=[self.mapView mapRectThatFits:zoomRect];
//выводим на экран получившийся прямоугольник с отступами 50 со всех сторон
[self.mapView setVisibleMapRect:zoomRect edgePadding:UIEdgeInsetsMake(50, 50, 50, 50) animated:YES];
}
Изменим метод для перемещения пина, таким образом, чтобы после завершения перемещения пина выводилась его координаты:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState
fromOldState:(MKAnnotationViewDragState)oldState{
//если состояние = конец перемещния
if (newState==MKAnnotationViewDragStateEnding) {
//получаем координаты в градусах из аннотации
CLLocationCoordinate2D location=view.annotation.coordinate;
//преобразуем в плоские координаты
MKMapPoint point = MKMapPointForCoordinate(location);
//выводим координаты в градусах и в MKMapPoint
NSLog(@"\nLocation={%@, %@}\nPoint = %@",@(location.latitude),@(location.longitude),MKStringFromMapPoint(point));
}
}
Продолжение в следующем уроке
Дополнение:
Объявить переменную:
@property (nonatomic,strong) CLLocationManager *locationManager;
@interface ViewController () <MKMapViewDelegate,CLLocationManagerDelegate>
вставить следующий код в viewDidLoad:
self.mapView.showsUserLocation=YES;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.mapView.delegate = self;
[self.locationManager requestWhenInUseAuthorization];
Так же в info.plist необходимо добавить новое поле типа String:NSLocationWhenInUseUsageDescription с приветствием которое будет выводиться в запросе геопозиции, например: MegaMap would like to use your location.
Комментариев нет:
Отправить комментарий