Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Карты — это общая функция во всех современных мобильных операционных системах. IOS предлагает поддержку сопоставления в собственном коде с помощью платформы Map Kit. С помощью комплекта карт приложения могут легко добавлять расширенные интерактивные карты. Эти карты можно настроить различными способами, например добавление заметок для пометки расположений на карте и перекладывание графики произвольных фигур. Пакет карт даже имеет встроенную поддержку для отображения текущего расположения устройства.
Добавление карты
Добавление карты в приложение выполняется путем добавления экземпляра MKMapView в иерархию представлений, как показано ниже:
// map is an MKMapView declared as a class variable
map = new MKMapView (UIScreen.MainScreen.Bounds);
View = map;
MKMapViewUIView— подкласс, отображающий карту. Простое добавление карты с помощью приведенного выше кода создает интерактивную карту:

Стиль карты
MKMapView поддерживает 3 различных стиля карт. Чтобы применить стиль карты, просто задайте MapType для свойства значение из MKMapType перечисления:
map.MapType = MKMapType.Standard; //road map
map.MapType = MKMapType.Satellite;
map.MapType = MKMapType.Hybrid;
На следующем снимку экрана показаны различные стили карт, доступные:

Сдвиг и масштабирование
MKMapView включает поддержку функций интерактивности карты, таких как:
- Масштабирование с помощью жеста сцепления
- Сдвиг с помощью жеста сдвига
Эти функции можно включить или отключить, просто задав ZoomEnabled и ScrollEnabled свойства экземпляра MKMapView , где значение по умолчанию верно для обоих. Например, чтобы отобразить статическую карту, просто задайте для соответствующих свойств значение false:
map.ZoomEnabled = false;
map.ScrollEnabled = false;
Местонахождение пользователей
Помимо взаимодействия с пользователем, MKMapView также имеет встроенную поддержку отображения расположения устройства. Это делается с помощью платформы "Основное расположение ". Прежде чем получить доступ к расположению пользователя, необходимо указать пользователю запрос. Для этого создайте экземпляр CLLocationManager и вызов RequestWhenInUseAuthorization.
CLLocationManager locationManager = new CLLocationManager();
locationManager.RequestWhenInUseAuthorization();
//locationManager.RequestAlwaysAuthorization(); //requests permission for access to location data while running in the background
Обратите внимание, что в версиях iOS до 8.0 попытка вызова RequestWhenInUseAuthorization приведет к ошибке. Перед этим вызовом обязательно проверьте версию iOS, если вы планируете поддерживать версии до 8.
Для доступа к расположению пользователя также требуются изменения в Info.plist. Необходимо задать следующие ключи, связанные с данными о расположении:
- NSLocationWhenInUseUsageDescription для доступа к расположению пользователя во время его взаимодействия с приложением.
- NSLocationAlwaysUsageDescription для доступа приложения к расположению пользователя в фоновом режиме.
Эти ключи можно добавить, открыв Info.plist и выбрав источник в нижней части редактора.
После обновления Info.plist и запроса пользователя на доступ к его расположению можно отобразить расположение пользователя на карте, установив ShowsUserLocation для свойства значение true:
map.ShowsUserLocation = true;

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

Добавление заметки
Сама заметка состоит из двух частей:
- Объект
MKAnnotation, содержащий данные модели о заметке, например название и расположение заметки. - Объект
MKAnnotationView, содержащий изображение для отображения и при необходимости выноски, отображаемой при касании заметки пользователем.
Map Kit использует шаблон делегирования MKMapView iOS для добавления примечаний к карте, где Delegate свойство объекта задано экземпляромMKMapViewDelegate. Это реализация этого делегата, которая отвечает за возврат MKAnnotationView заметки.
Чтобы добавить заметку, сначала добавляется заметка путем вызова AddAnnotations экземпляра MKMapView :
// add an annotation
map.AddAnnotations (new MKPointAnnotation (){
Title="MyAnnotation",
Coordinate = new CLLocationCoordinate2D (42.364260, -71.120824)
});
Когда расположение заметки становится видимым на карте, MKMapView метод делегата GetViewForAnnotation вызывается для отображения MKAnnotationView .
Например, следующий код возвращает предоставленный MKPinAnnotationViewсистемой код:
string pId = "PinAnnotation";
public override MKAnnotationView GetViewForAnnotation (MKMapView mapView, NSObject annotation)
{
if (annotation is MKUserLocation)
return null;
// create pin annotation view
MKAnnotationView pinView = (MKPinAnnotationView)mapView.DequeueReusableAnnotation (pId);
if (pinView == null)
pinView = new MKPinAnnotationView (annotation, pId);
((MKPinAnnotationView)pinView).PinColor = MKPinAnnotationColor.Red;
pinView.CanShowCallout = true;
return pinView;
}
Повторное выполнение заметок
Чтобы сохранить память, MKMapView можно использовать представление заметки для повторного использования, аналогично тому, как ячейки таблицы повторно используются. Получение представления заметок из пула выполняется с вызовом:DequeueReusableAnnotation
MKAnnotationView pinView = (MKPinAnnotationView)mapView.DequeueReusableAnnotation (pId);
Отображение выносок
Как упоминалось ранее, заметка может при необходимости отображать выноску. Чтобы отобразить выноску, просто установите CanShowCallout значение true на объекте MKAnnotationView. Это приводит к отображению заголовка заметки при нажатии заметки, как показано ниже.

Настройка выноски
Выноска также можно настроить для отображения представлений слева и справа, как показано ниже:
pinView.RightCalloutAccessoryView = UIButton.FromType (UIButtonType.DetailDisclosure);
pinView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile ("monkey.png"));
Этот код приводит к следующему выноске:

Чтобы обработать правую аксессуару, просто реализуйте CalloutAccessoryControlTapped метод в следующих MKMapViewDelegateэлементах:
public override void CalloutAccessoryControlTapped (MKMapView mapView, MKAnnotationView view, UIControl control)
{
...
}
Наложения
Другим способом слоя графики на карте является использование наложений. Наложения позволяют рисовать графическое содержимое, которое масштабируется вместе с картой. IOS обеспечивает поддержку нескольких типов наложений, в том числе:
- Многоугольники — обычно используются для выделения некоторых регионов на карте.
- Polylines - Часто видно при отображении маршрута.
- Круги — используются для выделения круговой области карты.
Кроме того, пользовательские наложения можно создать для отображения произвольных геометрий с детализированный настраиваемый код рисования. Например, погодный радар будет хорошим кандидатом для пользовательского наложения.
Добавление наложения
Аналогично заметкам, добавление наложения включает в себя 2 части:
- Создание объекта модели для наложения и его добавление в
MKMapViewнего. - Создание представления для наложения в элементе
MKMapViewDelegate.
Модель для наложения может быть любым MKShape подклассом. Xamarin.iOS включает MKShape подклассы для многоугольников, полилайнов и кругов, через MKPolygonMKPolyline классы соответственноMKCircle.
Например, следующий код используется для добавления MKCircle:
var circleOverlay = MKCircle.Circle (mapCenter, 1000);
map.AddOverlay (circleOverlay);
Представление для наложения — это MKOverlayView экземпляр, возвращаемый GetViewForOverlay в объекте MKMapViewDelegate. Каждый MKShape имеет соответствующий MKOverlayView , который знает, как отобразить заданную фигуру. Для MKPolygon этого есть MKPolygonView. Аналогично, MKPolyline соответствует и для MKCircle этого естьMKCircleViewMKPolylineView.
Например, следующий код возвращает MKCircleView значение для MKCircle:
public override MKOverlayView GetViewForOverlay (MKMapView mapView, NSObject overlay)
{
var circleOverlay = overlay as MKCircle;
var circleView = new MKCircleView (circleOverlay);
circleView.FillColor = UIColor.Blue;
return circleView;
}
Откроется круг на карте, как показано ниже.

Локальный поиск
IOS включает локальный API поиска с пакетом map, который позволяет асинхронно искать точки интереса в указанном географическом регионе.
Чтобы выполнить локальный поиск, приложение должно выполнить следующие действия:
- Создайте объект
MKLocalSearchRequest. MKLocalSearchСоздайте объект изMKLocalSearchRequestобъекта .StartВызовите метод объектаMKLocalSearch.MKLocalSearchResponseПолучение объекта в обратном вызове.
Сам API локального поиска не предоставляет пользовательского интерфейса. Он даже не требует использования карты. Однако для практического использования локального поиска приложение должно предоставить какой-то способ указать поисковый запрос и отобразить результаты. Кроме того, так как результаты будут содержать данные о расположении, они часто будут отображаться на карте.
Добавление пользовательского интерфейса локального поиска
Один из способов принять входные данные поиска — с UISearchBarпомощью функции, предоставленной и UISearchController отображающей результаты в таблице.
Следующий код добавляет UISearchController (которое имеет свойство панели поиска) в ViewDidLoad методе MapViewController:
//Creates an instance of a custom View Controller that holds the results
var searchResultsController = new SearchResultsViewController (map);
//Creates a search controller updater
var searchUpdater = new SearchResultsUpdator ();
searchUpdater.UpdateSearchResults += searchResultsController.Search;
//add the search controller
searchController = new UISearchController (searchResultsController) {
SearchResultsUpdater = searchUpdater
};
//format the search bar
searchController.SearchBar.SizeToFit ();
searchController.SearchBar.SearchBarStyle = UISearchBarStyle.Minimal;
searchController.SearchBar.Placeholder = "Enter a search query";
//the search bar is contained in the navigation bar, so it should be visible
searchController.HidesNavigationBarDuringPresentation = false;
//Ensure the searchResultsController is presented in the current View Controller
DefinesPresentationContext = true;
//Set the search bar in the navigation bar
NavigationItem.TitleView = searchController.SearchBar;
Обратите внимание, что вы несете ответственность за включение объекта панели поиска в пользовательский интерфейс. В этом примере мы назначили его в TitleView панели навигации, но если вы не используете контроллер навигации в приложении, вам придется найти другое место для его отображения.
В этом фрагменте кода мы создали другой контроллер пользовательского представления , searchResultsController который отображает результаты поиска, а затем мы использовали этот объект для создания объекта контроллера поиска. Мы также создали новый обработчик обновления поиска, который становится активным при взаимодействии пользователя с строкой поиска. Он получает уведомления о поиске с каждым нажатием клавиш и отвечает за обновление пользовательского интерфейса.
Мы рассмотрим, как реализовать как в этом руководстве, searchResultsUpdater так searchResultsController и далее.
Это приводит к отображению панели поиска на карте, как показано ниже:

Отображение результатов поиска
Чтобы отобразить результаты поиска, необходимо создать пользовательский контроллер представления; обычно .UITableViewController Как показано выше, конструктор searchResultsController передается конструктору searchController при его создании.
Следующий код является примером создания этого пользовательского контроллера представления:
public class SearchResultsViewController : UITableViewController
{
static readonly string mapItemCellId = "mapItemCellId";
MKMapView map;
public List<MKMapItem> MapItems { get; set; }
public SearchResultsViewController (MKMapView map)
{
this.map = map;
MapItems = new List<MKMapItem> ();
}
public override nint RowsInSection (UITableView tableView, nint section)
{
return MapItems.Count;
}
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell (mapItemCellId);
if (cell == null)
cell = new UITableViewCell ();
cell.TextLabel.Text = MapItems [indexPath.Row].Name;
return cell;
}
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
// add item to map
CLLocationCoordinate2D coord = MapItems [indexPath.Row].Placemark.Location.Coordinate;
map.AddAnnotations (new MKPointAnnotation () {
Title = MapItems [indexPath.Row].Name,
Coordinate = coord
});
map.SetCenterCoordinate (coord, true);
DismissViewController (false, null);
}
public void Search (string forSearchString)
{
// create search request
var searchRequest = new MKLocalSearchRequest ();
searchRequest.NaturalLanguageQuery = forSearchString;
searchRequest.Region = new MKCoordinateRegion (map.UserLocation.Coordinate, new MKCoordinateSpan (0.25, 0.25));
// perform search
var localSearch = new MKLocalSearch (searchRequest);
localSearch.Start (delegate (MKLocalSearchResponse response, NSError error) {
if (response != null && error == null) {
this.MapItems = response.MapItems.ToList ();
this.TableView.ReloadData ();
} else {
Console.WriteLine ("local search error: {0}", error);
}
});
}
}
Обновление результатов поиска
Он SearchResultsUpdater выступает в качестве посредника между searchControllerстрокой поиска и результатами поиска.
В этом примере сначала необходимо создать метод поиска в .SearchResultsViewController Для этого необходимо создать MKLocalSearch объект и использовать его для выдачи поиска MKLocalSearchRequest, результаты извлекаются в обратном вызове, переданном Start методу MKLocalSearch объекта. Затем результаты возвращаются в объекте MKLocalSearchResponse , содержав массив MKMapItem объектов:
public void Search (string forSearchString)
{
// create search request
var searchRequest = new MKLocalSearchRequest ();
searchRequest.NaturalLanguageQuery = forSearchString;
searchRequest.Region = new MKCoordinateRegion (map.UserLocation.Coordinate, new MKCoordinateSpan (0.25, 0.25));
// perform search
var localSearch = new MKLocalSearch (searchRequest);
localSearch.Start (delegate (MKLocalSearchResponse response, NSError error) {
if (response != null && error == null) {
this.MapItems = response.MapItems.ToList ();
this.TableView.ReloadData ();
} else {
Console.WriteLine ("local search error: {0}", error);
}
});
}
Затем мы MapViewController создадим настраиваемую реализацию UISearchResultsUpdating, которая назначается SearchResultsUpdater свойству нашего searchController раздела "Добавление локального пользовательского интерфейса поиска":
public class SearchResultsUpdator : UISearchResultsUpdating
{
public event Action<string> UpdateSearchResults = delegate {};
public override void UpdateSearchResultsForSearchController (UISearchController searchController)
{
this.UpdateSearchResults (searchController.SearchBar.Text);
}
}
Приведенная выше реализация добавляет заметку к карте при выборе элемента из результатов, как показано ниже:

Внимание
UISearchController реализован в iOS 8. Если вы хотите поддерживать устройства раньше этого, вам потребуется использовать UISearchDisplayController.
Итоги
В этой статье рассматривается платформа пакета карт для iOS. Во-первых, он рассмотрел, как MKMapView класс позволяет интерактивным картам включаться в приложение. Затем он продемонстрировал, как дополнительно настроить карты с помощью заметок и наложений. Наконец, она изучила возможности локального поиска, добавленные в Пакет карт с iOS 6.1, в котором показано, как использовать запросы на основе расположения для точек интереса и добавить их на карту.