Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Mapy jsou běžnou funkcí ve všech moderních mobilních operačních systémech. iOS nabízí nativně podporu mapování prostřednictvím architektury Map Kit. Pomocí sady Map Kit můžou aplikace snadno přidávat bohaté interaktivní mapy. Tyto mapy lze přizpůsobit různými způsoby, například přidáním poznámek k označení umístění na mapě a překrytím grafiky libovolných obrazců. Map Kit má dokonce integrovanou podporu pro zobrazení aktuálního umístění zařízení.
Přidání mapy
Přidání mapy do aplikace se provádí přidáním MKMapView instance do hierarchie zobrazení, jak je znázorněno níže:
// map is an MKMapView declared as a class variable
map = new MKMapView (UIScreen.MainScreen.Bounds);
View = map;
MKMapViewUIView je podtřída, která zobrazuje mapu. Jednoduše přidáním mapy pomocí výše uvedeného kódu vznikne interaktivní mapa:

Styl mapy
MKMapView podporuje 3 různé styly map. Pokud chcete použít styl mapy, jednoduše nastavte MapType vlastnost na hodnotu z výčtu MKMapType :
map.MapType = MKMapType.Standard; //road map
map.MapType = MKMapType.Satellite;
map.MapType = MKMapType.Hybrid;
Následující snímek obrazovky ukazuje různé dostupné styly mapy:

Posouvání a přiblížení
MKMapView zahrnuje podporu pro funkce interaktivity mapování, jako jsou:
- Přiblížení gestem připnutí
- Posouvání pomocí gesta posouvání
Tyto funkce je možné povolit nebo zakázat jednoduchým nastavením ZoomEnabled a ScrollEnabled vlastnostmi MKMapView instance, kde výchozí hodnota platí pro oba. Pokud chcete například zobrazit statickou mapu, jednoduše nastavte odpovídající vlastnosti na false:
map.ZoomEnabled = false;
map.ScrollEnabled = false;
Umístění uživatele
Kromě interakce MKMapView uživatelů má také integrovanou podporu pro zobrazení polohy zařízení. Dělá to pomocí architektury Core Location . Než budete mít přístup k umístění uživatele, musíte uživatele vyzvat. Chcete-li to provést, vytvořte instanci CLLocationManager a volání RequestWhenInUseAuthorization.
CLLocationManager locationManager = new CLLocationManager();
locationManager.RequestWhenInUseAuthorization();
//locationManager.RequestAlwaysAuthorization(); //requests permission for access to location data while running in the background
Všimněte si, že při pokusu o volání RequestWhenInUseAuthorization ve verzích iOS starších než 8.0 dojde k chybě. Před voláním nezapomeňte zkontrolovat verzi iOS, pokud máte v úmyslu podporovat verze starší než 8.
Přístup k umístění uživatele také vyžaduje úpravy souboru Info.plist. Měly by být nastaveny následující klíče týkající se údajů o poloze:
- NSLocationWhenInUseUsageDescription – Pokud při interakci s vaší aplikací přistupujete k umístění uživatele.
- NSLocationAlwaysUsageDescription – Pokud vaše aplikace přistupuje k umístění uživatele na pozadí.
Tyto klíče můžete přidat tak, že otevřete Soubor Info.plist a vyberete Zdroj v dolní části editoru.
Po aktualizaci souboru Info.plist a zobrazení výzvy uživateli, aby získal oprávnění pro přístup k jeho umístění, můžete zobrazit polohu uživatele na mapě nastavením ShowsUserLocation vlastnosti na hodnotu true:
map.ShowsUserLocation = true;

Poznámky
MKMapView podporuje také zobrazování obrázků, označovaných jako poznámky, na mapě. Můžou to být vlastní image nebo systémově definované špendlíky různých barev. Například následující snímek obrazovky ukazuje mapu s připnutím i vlastním obrázkem:

Přidání poznámky
Samotná poznámka má dvě části:
- Objekt
MKAnnotation, který obsahuje data modelu o anotaci, například název a umístění poznámky. - ,
MKAnnotationViewkterý obsahuje obrázek, který se má zobrazit, a volitelně popisek, který se zobrazí, když uživatel klepne na poznámku.
Map Kit používá vzor delegování iOS k přidání poznámek do mapy, kde Delegate vlastnost objektu MKMapView je nastavena na instanci objektu MKMapViewDelegate. Je to implementace tohoto delegáta, která je zodpovědná za vrácení poznámky MKAnnotationView .
Pokud chcete přidat poznámku, nejprve se přidá poznámka voláním AddAnnotations instance MKMapView :
// add an annotation
map.AddAnnotations (new MKPointAnnotation (){
Title="MyAnnotation",
Coordinate = new CLLocationCoordinate2D (42.364260, -71.120824)
});
Když se na mapě zobrazí umístění poznámek, zavolá metoda delegátaGetViewForAnnotation, MKMapView aby se zobrazilaMKAnnotationView.
Následující kód například vrátí systém 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;
}
Opakované přidávání poznámek
Chcete-li ušetřit paměť, MKMapView umožňuje, aby bylo zobrazení poznámek ve fondu pro opakované použití, podobně jako jsou buňky tabulky opakovaně používány. Získání zobrazení poznámek z fondu se provádí voláním DequeueReusableAnnotation:
MKAnnotationView pinView = (MKPinAnnotationView)mapView.DequeueReusableAnnotation (pId);
Zobrazení bublinových popisků
Jak už bylo zmíněno dříve, poznámka může volitelně zobrazit bublinový popisek. Chcete-li zobrazit bublinový popisek jednoduše nastaven CanShowCallout na hodnotu true na kartě MKAnnotationView. Výsledkem je zobrazení názvu poznámky při klepnutí na poznámku, jak je znázorněno na obrázku:

Přizpůsobení bublinového popisku
Popisek lze také přizpůsobit tak, aby zobrazoval zobrazení levého a pravého přístupového objektu, jak je znázorněno níže:
pinView.RightCalloutAccessoryView = UIButton.FromType (UIButtonType.DetailDisclosure);
pinView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile ("monkey.png"));
Výsledkem tohoto kódu je následující bublinový popisek:

Pokud chcete pracovat s uživatelem klepnutím na správné příslušenství, jednoduše implementujte metodu CalloutAccessoryControlTapped v :MKMapViewDelegate
public override void CalloutAccessoryControlTapped (MKMapView mapView, MKAnnotationView view, UIControl control)
{
...
}
Překryvy
Další způsob, jak vrstvit grafiku na mapě, je použití překrytí. Překryvné vrstvy podporují grafický obsah výkresu, který se při přiblížení zvětšuje s mapou. iOS poskytuje podporu pro několik typů překryvů, mezi které patří:
- Mnohoúhelníky – běžně se používá ke zvýraznění určité oblasti na mapě.
- Křivky – často se zobrazuje při zobrazení trasy.
- Kruhy – slouží ke zvýraznění kruhové oblasti mapy.
Kromě toho je možné vytvořit vlastní překrytí, aby bylo možné zobrazit libovolné geometrie s podrobným přizpůsobeným kódem výkresu. Například meteorologický radar by byl vhodným kandidátem pro vlastní překryv.
Přidání překryvného objektu
Podobně jako poznámky zahrnuje přidání překrytí 2 části:
- Vytvoření objektu modelu pro překrytí a jeho přidání do objektu
MKMapView. - Vytvoření zobrazení pro překryvné zobrazení v objektu
MKMapViewDelegate.
Model pro překryvné vrstvy může být libovolná MKShape podtřída. Xamarin.iOS obsahuje MKShape podtřídy pro mnohoúhelníky, lomené čáry a kruhy prostřednictvím MKPolyline MKPolygontříd a MKCircle tříd.
Například následující kód se používá k přidání MKCircle:
var circleOverlay = MKCircle.Circle (mapCenter, 1000);
map.AddOverlay (circleOverlay);
Zobrazení pro překryvné zobrazení je MKOverlayView instance, která je vrácena GetViewForOverlay v objektu MKMapViewDelegate. Každá z nich MKShape má odpovídající, MKOverlayView která ví, jak zobrazit daný obrazec. Pro MKPolygon tam je MKPolygonView. Podobně odpovídá MKPolyline MKPolylineView, a pro MKCircle tam je MKCircleView.
Například následující kód vrátí MKCircleView pro: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;
}
Zobrazí se kruh na mapě, jak je znázorněno:

Místní vyhledávání
iOS obsahuje rozhraní API pro místní vyhledávání se sadou Map Kit, které umožňuje asynchronní vyhledávání bodů zájmu v zadané geografické oblasti.
Pokud chcete provést místní vyhledávání, musí aplikace postupovat takto:
- Vytvořit
MKLocalSearchRequestobjekt. - Vytvořte objekt
MKLocalSearchz objektuMKLocalSearchRequest. - Zavolejte metodu
StartobjektuMKLocalSearch. MKLocalSearchResponseNačtěte objekt v zpětném volání.
Samotné rozhraní API místního vyhledávání neposkytuje žádné uživatelské rozhraní. Nevyžaduje ani použití mapy. Aby se ale místní vyhledávání prakticky využilo, musí aplikace poskytnout nějaký způsob, jak zadat vyhledávací dotaz a zobrazit výsledky. Vzhledem k tomu, že výsledky budou obsahovat údaje o poloze, často dávají smysl je zobrazit na mapě.
Přidání uživatelského rozhraní místního vyhledávání
Jedním zezpůsobůch UISearchBarUISearchController
Následující kód přidá UISearchController (který má vlastnost vyhledávacího pruhu) v ViewDidLoad metodě 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;
Všimněte si, že zodpovídáte za začlenění objektu vyhledávacího panelu do uživatelského rozhraní. V tomto příkladu jsme ho přiřadili k ovládacímu prvku TitleView navigačního panelu, ale pokud ve své aplikaci nepoužíváte navigační kontroler, budete muset najít jiné místo, kde ho chcete zobrazit.
V tomto fragmentu kódu jsme vytvořili další vlastní kontroler zobrazení – searchResultsController který zobrazuje výsledky hledání a pak jsme tento objekt použili k vytvoření objektu kontroleru vyhledávání. Vytvořili jsme také nový aktualizátor vyhledávání, který se aktivuje, když uživatel pracuje s panelem hledání. Přijímá oznámení o hledáních pomocí jednotlivých klávesových úhošť a zodpovídá za aktualizaci uživatelského rozhraní.
Podíváme se, jak implementovat jak tuto searchResultsController verzi, tak i searchResultsUpdater později v této příručce.
Výsledkem je panel hledání zobrazený na mapě, jak je znázorněno níže:

Zobrazení výsledků hledání
Abychom mohli zobrazit výsledky hledání, musíme vytvořit vlastní kontroler zobrazení; normálně a UITableViewController. Jak je znázorněno výše, searchResultsController předá se konstruktoru searchController při jeho vytváření.
Následující kód je příkladem vytvoření tohoto vlastního kontroleru zobrazení:
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);
}
});
}
}
Aktualizace výsledků hledání
Jedná SearchResultsUpdater se jako mediátor mezi searchControllervyhledávacím panelem a výsledky hledání.
V tomto příkladu musíme nejprve vytvořit vyhledávací metodu v souboru SearchResultsViewController. K tomu musíme vytvořit MKLocalSearch objekt a použít ho k vydání hledání , MKLocalSearchRequestvýsledky se načtou v zpětném volání předané Start metodě objektu MKLocalSearch . Výsledky se pak vrátí v objektu MKLocalSearchResponse obsahujícím pole MKMapItem objektů:
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);
}
});
}
Pak v naší MapViewController vytvoříme vlastní implementaci UISearchResultsUpdating, která je přiřazena k SearchResultsUpdater vlastnosti našeho searchController v části Přidání místního vyhledávacího uživatelského rozhraní :
public class SearchResultsUpdator : UISearchResultsUpdating
{
public event Action<string> UpdateSearchResults = delegate {};
public override void UpdateSearchResultsForSearchController (UISearchController searchController)
{
this.UpdateSearchResults (searchController.SearchBar.Text);
}
}
Výše uvedená implementace přidá do mapy poznámku, když je položka vybrána z výsledků, jak je znázorněno níže:

Důležité
UISearchController byla implementována v iOSu 8. Pokud chcete zařízení podporovat dříve, budete muset použít UISearchDisplayController.
Shrnutí
Tento článek prozkoumal architekturu mapových sad pro iOS. Nejprve se podívala na to, jak MKMapView třída umožňuje zahrnutí interaktivních map do aplikace. Pak ukázal, jak dále přizpůsobit mapy pomocí poznámek a překryvných objektů. Nakonec prozkoumala možnosti místního vyhledávání, které byly přidány do mapové sady s iOSem 6.1, a ukázala, jak použít provádění dotazů založených na poloze pro body zájmu a přidat je do mapy.