Xamarin.iOS'ta Haritalar
Haritalar, tüm modern mobil işletim sistemlerinde yaygın olarak kullanılan bir özelliktir. iOS, Harita Seti çerçevesi aracılığıyla yerel olarak eşleme desteği sunar. Map Kit ile uygulamalar kolayca zengin, etkileşimli haritalar ekleyebilir. Bu haritalar, haritadaki konumları işaretlemek için ek açıklamalar ekleme ve rastgele şekillerin grafiklerini katmanlama gibi çeşitli yollarla özelleştirilebilir. Harita Seti' nin cihazın geçerli konumunu göstermek için yerleşik desteği bile vardır.
Harita Ekleme
Bir uygulamaya eşleme eklemek, aşağıda gösterildiği gibi görünüm hiyerarşisine bir MKMapView
örnek eklenerek gerçekleştirilir:
// map is an MKMapView declared as a class variable
map = new MKMapView (UIScreen.MainScreen.Bounds);
View = map;
MKMapView
, harita görüntüleyen bir UIView
alt sınıftır. Yukarıdaki kodu kullanarak haritanın eklenmesi etkileşimli bir harita oluşturur:
Harita Stili
MKMapView
3 farklı harita stilini destekler. Harita stili uygulamak için özelliğini sabit listesindeki MKMapType
bir değere ayarlamanız MapType
yeterlidir:
map.MapType = MKMapType.Standard; //road map
map.MapType = MKMapType.Satellite;
map.MapType = MKMapType.Hybrid;
Aşağıdaki ekran görüntüsünde kullanılabilen farklı harita stilleri gösterilmektedir:
Kaydırma ve Yakınlaştırma
MKMapView
aşağıdakiler gibi harita etkileşim özellikleri için destek içerir:
- Sıkıştırma hareketiyle yakınlaştırma
- Yatay kaydırma hareketiyle kaydırma
Bu özellikler, her ikisi için de varsayılan değerin ZoomEnabled
doğru olduğu örneğin ve ScrollEnabled
özellikleri MKMapView
ayarlanarak etkinleştirilebilir veya devre dışı bırakılabilir. Örneğin, statik bir harita görüntülemek için uygun özellikleri false olarak ayarlamanız yeterlidir:
map.ZoomEnabled = false;
map.ScrollEnabled = false;
Kullanıcı Konumu
Kullanıcı etkileşiminin yanı sıra, MKMapView
cihazın konumunu görüntülemeye yönelik yerleşik destek de vardır. Bunu Çekirdek Konum çerçevesini kullanarak yapar. Kullanıcının konumuna erişebilmeniz için önce kullanıcıya sormanız gerekir. Bunu yapmak için bir örneği CLLocationManager
oluşturun ve öğesini çağırın RequestWhenInUseAuthorization
.
CLLocationManager locationManager = new CLLocationManager();
locationManager.RequestWhenInUseAuthorization();
//locationManager.RequestAlwaysAuthorization(); //requests permission for access to location data while running in the background
iOS'un 8.0 öncesi sürümlerinde çağrılmaya RequestWhenInUseAuthorization
çalışılması hataya neden olur. 8'den önceki sürümleri desteklemek istiyorsanız bu çağrıyı yapmadan önce iOS sürümünü kontrol etmeyi unutmayın.
Kullanıcının konumuna erişmek için Info.plist dosyasında da değişiklik yapılması gerekir. Konum verileriyle ilgili aşağıdaki anahtarlar ayarlanmalıdır:
- NSLocationWhenInUseUsageDescription - Uygulamanızla etkileşim kurarken kullanıcının konumuna eriştiğiniz zaman için.
- NSLocationAlwaysUsageDescription - Uygulamanızın arka planda kullanıcının konumuna erişmesi için.
Info.plist dosyasını açıp düzenleyicinin alt kısmındaki Kaynak'ı seçerek bu anahtarları ekleyebilirsiniz.
Info.plist dosyasını güncelleştirdikten ve kullanıcıdan konumuna erişim izni istedikten sonra, özelliğini true olarak ayarlayarak ShowsUserLocation
kullanıcının konumunu haritada gösterebilirsiniz:
map.ShowsUserLocation = true;
Ek Açıklamalar
MKMapView
ayrıca ek açıklama olarak bilinen görüntülerin haritada görüntülenmesini de destekler. Bunlar özel görüntüler veya çeşitli renklerde sistem tanımlı raptiyeler olabilir. Örneğin, aşağıdaki ekran görüntüsünde hem pin hem de özel görüntü içeren bir harita gösterilmektedir:
Ek açıklama ekleme
Ek açıklamanın kendisi iki bölümden oluşur:
- Ek
MKAnnotation
açıklamanın başlığı ve konumu gibi ek açıklamayla ilgili model verilerini içeren nesnesi. - görüntülenecek
MKAnnotationView
görüntüyü içeren ve isteğe bağlı olarak kullanıcı ek açıklamaya dokunduğunda gösterilen bir açıklama balonu.
Map Kit, özelliğinin bir örneğine ayarlandığı Delegate
MKMapView
bir haritaya ek açıklamalar eklemek için iOS temsil desenini MKMapViewDelegate
kullanır. Ek açıklamayı döndürmekten sorumlu olan bu temsilcinin MKAnnotationView
uygulamasıdır.
Ek açıklama eklemek için önce örnekte çağrılarak AddAnnotations
MKMapView
ek açıklama eklenir:
// add an annotation
map.AddAnnotations (new MKPointAnnotation (){
Title="MyAnnotation",
Coordinate = new CLLocationCoordinate2D (42.364260, -71.120824)
});
Ek açıklamanın konumu haritada görünür hale geldiğinde, MKMapView
öğesinin görüntülenmesini sağlamak için temsilcisinin GetViewForAnnotation
MKAnnotationView
yöntemini çağırır.
Örneğin, aşağıdaki kod sistem tarafından sağlanan MKPinAnnotationView
bir döndürür:
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;
}
Ek Açıklamaları Yeniden Kullan
Bellek tasarrufu yapmak için, MKMapView
tablo hücrelerinin yeniden kullanılmasına benzer şekilde ek açıklama görünümünün yeniden kullanım için havuza alınmasına izin verir. Havuzdan ek açıklama görünümü elde etmek için DequeueReusableAnnotation
çağrısı yapılır:
MKAnnotationView pinView = (MKPinAnnotationView)mapView.DequeueReusableAnnotation (pId);
Belirtme Çizgilerini Gösterme
Daha önce belirtildiği gibi, ek açıklama isteğe bağlı olarak açıklama balonu gösterebilir. Belirtme çizgisinin üzerinde true olarak ayarlanması CanShowCallout
yeterlidir MKAnnotationView
. Bu, gösterildiği gibi ek açıklamaya dokunulduğunda ek açıklamanın başlığının görüntülenmesine neden olur:
Açıklama Balonunu Özelleştirme
Açıklama balonu, aşağıda gösterildiği gibi sol ve sağ aksesuar görünümlerini gösterecek şekilde de özelleştirilebilir:
pinView.RightCalloutAccessoryView = UIButton.FromType (UIButtonType.DetailDisclosure);
pinView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile ("monkey.png"));
Bu kod aşağıdaki açıklama balonunu döndürür:
Kullanıcının doğru aksesuara dokunmasını işlemek için yöntemini içinde MKMapViewDelegate
uygulamanız CalloutAccessoryControlTapped
yeterlidir:
public override void CalloutAccessoryControlTapped (MKMapView mapView, MKAnnotationView view, UIControl control)
{
...
}
Bindirmeler
Harita üzerinde grafik katmanı oluşturmanın bir diğer yolu da katman kullanmaktır. Yer paylaşımları, harita yakınlaştırıldıkça ölçeklendirilen grafik içerik çizmeyi destekler. iOS, aşağıdakiler dahil olmak üzere çeşitli katman türleri için destek sağlar:
- Çokgenler - Genellikle haritada bazı bölgeyi vurgulamak için kullanılır.
- Polilines - Genellikle bir yol gösterilirken görülür.
- Daireler - Haritanın dairesel bir alanını vurgulamak için kullanılır.
Ayrıca, ayrıntılı, özelleştirilmiş çizim koduyla rastgele geometrileri göstermek için özel katman oluşturulabilir. Örneğin, hava durumu radarı özel katman için iyi bir aday olacaktır.
Katman Ekleme
Ek açıklamalara benzer şekilde, katman ekleme işlemi 2 bölümden oluşur:
- Katman için bir model nesnesi oluşturma ve nesnesine
MKMapView
ekleme. - içindeki
MKMapViewDelegate
katman için bir görünüm oluşturma.
Katman modeli herhangi bir MKShape
alt sınıf olabilir. Xamarin.iOS, sırasıyla aracılığıyla MKPolyline
çokgenler, çok çizgiler ve daireler için alt sınıflar MKPolygon
ve MKCircle
sınıflar içerirMKShape
.
Örneğin, aşağıdaki kod bir MKCircle
eklemek için kullanılır:
var circleOverlay = MKCircle.Circle (mapCenter, 1000);
map.AddOverlay (circleOverlay);
Katman görünümü, içinde MKMapViewDelegate
tarafından GetViewForOverlay
döndürülen bir MKOverlayView
örnektir. Her MKShape
birinin, verilen şeklin nasıl görüntüleneceğini bilen bir karşılık geleni MKOverlayView
vardır. için MKPolygon
vardır MKPolygonView
. Benzer şekilde, MKPolyline
öğesine karşılık gelir MKPolylineView
ve MKCircle
için vardır MKCircleView
.
Örneğin, aşağıdaki kod için bir MKCircleView
MKCircle
döndürür:
public override MKOverlayView GetViewForOverlay (MKMapView mapView, NSObject overlay)
{
var circleOverlay = overlay as MKCircle;
var circleView = new MKCircleView (circleOverlay);
circleView.FillColor = UIColor.Blue;
return circleView;
}
Bu, haritada gösterildiği gibi bir daire görüntüler:
Yerel Arama
iOS, belirli bir coğrafi bölgedeki ilgi çekici noktalar için zaman uyumsuz aramalara olanak tanıyan Harita Seti ile yerel bir arama API'sini içerir.
Yerel arama gerçekleştirmek için uygulamanın şu adımları izlemesi gerekir:
- Nesne oluşturun
MKLocalSearchRequest
. - öğesinden
MKLocalSearchRequest
birMKLocalSearch
nesne oluşturun. - nesnesinde
Start
yöntemini çağırınMKLocalSearch
. MKLocalSearchResponse
Nesneyi bir geri çağırmada alın.
Yerel arama API'sinin kendisi kullanıcı arabirimi sağlamaz. Haritanın kullanılmasını bile gerektirmez. Ancak, yerel aramayı pratik bir şekilde kullanmak için bir uygulamanın arama sorgusu belirtmenin ve sonuçları görüntülemenin bir yolunu sağlaması gerekir. Buna ek olarak, sonuçlar konum verileri içereceğinden, bunları genellikle bir haritada göstermek mantıklı olacaktır.
Yerel Arama Kullanıcı Arabirimi Ekleme
Arama girişini kabul etmenin bir UISearchBar
yolu, tarafından sağlanan UISearchController
ve sonuçları bir tabloda görüntüleyen iledir.
Aşağıdaki kod yöntemine UISearchController
öğesini ekler (arama çubuğu özelliğine ViewDidLoad
sahiptir).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;
Arama çubuğu nesnesini kullanıcı arabirimine dahil etme sorumluluğunuz olduğunu unutmayın. Bu örnekte, gezinti çubuğunun TitleView'unu atadık, ancak uygulamanızda bir gezinti denetleyicisi kullanmıyorsanız, bunu görüntülemek için başka bir yer bulmanız gerekir.
Bu kod parçacığında, arama sonuçlarını görüntüleyen başka bir özel görünüm denetleyicisi searchResultsController
oluşturduk ve ardından arama denetleyicisi nesnemizi oluşturmak için bu nesneyi kullandık. Kullanıcı arama çubuğuyla etkileşim kurduğunda etkin hale gelen yeni bir arama güncelleştirici de oluşturduk. Her tuş vuruşuyla yapılan aramalar hakkında bildirimler alır ve kullanıcı arabirimini güncelleştirmekle sorumludur.
Bu kılavuzun hem hem de sonraki sürümlerinin searchResultsController
searchResultsUpdater
nasıl uygulanacağını inceleyeceğiz.
Bu, aşağıda gösterildiği gibi harita üzerinde görüntülenen bir arama çubuğuyla sonuçlanır:
Arama Sonuçlarını Görüntüleme
Arama sonuçlarını görüntülemek için özel bir Görünüm Denetleyicisi oluşturmamız gerekir; normalde bir UITableViewController
. Yukarıda gösterildiği gibi, searchResultsController
oluşturulurken oluşturucusunun searchController
öğesine geçirilir.
Aşağıdaki kod, bu özel Görünüm Denetleyicisinin nasıl oluşturulacağını gösteren bir örnektir:
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);
}
});
}
}
Arama Sonuçlarını Güncelleştirme
, SearchResultsUpdater
arama çubuğu ve arama sonuçları arasında searchController
bir aracı görevi görür.
Bu örnekte, önce içinde SearchResultsViewController
arama yöntemini oluşturmamız gerekir. Bunu yapmak için bir MKLocalSearch
nesnesi oluşturmalı ve bir için arama yapmak için MKLocalSearchRequest
bunu kullanmalıyız. Sonuçlar, nesnesinin Start
MKLocalSearch
yöntemine geçirilen bir geri çağırmada alınır. Sonuçlar daha sonra bir MKLocalSearchResponse
nesne dizisi içeren bir nesnede MKMapItem
döndürülür:
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);
}
});
}
Ardından, yerel MapViewController
arama kullanıcı arabirimi ekleme bölümünde özelliğine SearchResultsUpdater
searchController
atanan özel UISearchResultsUpdating
uygulamasını oluşturacağız:
public class SearchResultsUpdator : UISearchResultsUpdating
{
public event Action<string> UpdateSearchResults = delegate {};
public override void UpdateSearchResultsForSearchController (UISearchController searchController)
{
this.UpdateSearchResults (searchController.SearchBar.Text);
}
}
Yukarıdaki uygulama, aşağıda gösterildiği gibi sonuçlardan bir öğe seçildiğinde haritaya bir ek açıklama ekler:
Önemli
UISearchController
iOS 8'de uygulandı. Bundan önceki cihazları desteklemek istiyorsanız kullanmanız gerekir UISearchDisplayController
.
Özet
Bu makalede iOS için Harita Seti çerçevesi incelendi. İlk olarak, sınıfın etkileşimli haritaların MKMapView
bir uygulamaya dahil edilmesine nasıl izin verdiğine baktı. Ardından ek açıklamaları ve katmanları kullanarak haritaları nasıl daha fazla özelleştirebileceğinizi gösterdi. Son olarak, iOS 6.1 ile Harita Seti'ne eklenen yerel arama özelliklerini inceleyerek ilgi çekici noktalar için konum tabanlı sorgular gerçekleştirmeyi ve bunları bir haritaya eklemeyi gösterdi.