Peta di Xamarin.iOS
Peta adalah fitur umum di semua sistem operasi seluler modern. iOS menawarkan dukungan pemetaan secara asli melalui kerangka kerja Map Kit. Dengan Map Kit, aplikasi dapat dengan mudah menambahkan peta interaktif yang kaya. Peta ini dapat disesuaikan dengan berbagai cara, seperti menambahkan anotasi untuk menandai lokasi di peta, dan melapisi grafik bentuk arbitrer. Map Kit bahkan memiliki dukungan bawaan untuk menampilkan lokasi perangkat saat ini.
Menambahkan Peta
Menambahkan peta ke aplikasi dilakukan dengan menambahkan MKMapView
instans ke hierarki tampilan, seperti yang ditunjukkan di bawah ini:
// map is an MKMapView declared as a class variable
map = new MKMapView (UIScreen.MainScreen.Bounds);
View = map;
MKMapView
adalah UIView
subkelas yang menampilkan peta. Cukup menambahkan peta menggunakan kode di atas menghasilkan peta interaktif:
Gaya Peta
MKMapView
mendukung 3 gaya peta yang berbeda. Untuk menerapkan gaya peta, cukup atur MapType
properti ke nilai dari MKMapType
enumerasi:
map.MapType = MKMapType.Standard; //road map
map.MapType = MKMapType.Satellite;
map.MapType = MKMapType.Hybrid;
Cuplikan layar berikut menunjukkan berbagai gaya peta yang tersedia:
Panning dan Zooming
MKMapView
termasuk dukungan untuk fitur interaktivitas peta seperti:
- Memperbesar melalui gerakan mencubit
- Panning melalui gerakan pan
Fitur-fitur ini dapat diaktifkan atau dinonaktifkan hanya dengan mengatur ZoomEnabled
properti MKMapView
dan ScrollEnabled
instans, di mana nilai default benar untuk keduanya. Misalnya, untuk menampilkan peta statis, cukup atur properti yang sesuai ke false:
map.ZoomEnabled = false;
map.ScrollEnabled = false;
Lokasi Pengguna
Selain interaksi pengguna, MKMapView
juga memiliki dukungan bawaan untuk menampilkan lokasi perangkat. Ini dilakukan menggunakan kerangka kerja Lokasi Inti. Sebelum dapat mengakses lokasi pengguna, Anda harus meminta pengguna. Untuk melakukan ini, buat instans CLLocationManager
dan panggil RequestWhenInUseAuthorization
.
CLLocationManager locationManager = new CLLocationManager();
locationManager.RequestWhenInUseAuthorization();
//locationManager.RequestAlwaysAuthorization(); //requests permission for access to location data while running in the background
Perhatikan bahwa dalam versi iOS sebelum 8.0, mencoba memanggil RequestWhenInUseAuthorization
akan mengakibatkan kesalahan. Pastikan untuk memeriksa versi iOS sebelum melakukan panggilan tersebut jika Anda ingin mendukung versi sebelum 8.
Mengakses lokasi pengguna juga memerlukan modifikasi pada Info.plist. Kunci berikut yang berkaitan dengan data lokasi harus diatur:
- NSLocationWhenInUseUsageDescription - Untuk saat Anda mengakses lokasi pengguna saat mereka berinteraksi dengan aplikasi Anda.
- NSLocationAlwaysUsageDescription - Untuk saat aplikasi Anda mengakses lokasi pengguna di latar belakang.
Anda dapat menambahkan kunci tersebut dengan membuka Info.plist dan memilih Sumber di bagian bawah editor.
Setelah memperbarui Info.plist dan meminta izin kepada pengguna untuk mengakses lokasi mereka, Anda dapat menampilkan lokasi pengguna di peta dengan mengatur ShowsUserLocation
properti ke true:
map.ShowsUserLocation = true;
Anotasi
MKMapView
juga mendukung menampilkan gambar, yang dikenal sebagai anotasi, di peta. Ini dapat berupa gambar kustom atau pin yang ditentukan sistem dari berbagai warna. Misalnya, cuplikan layar berikut menunjukkan peta dengan pin dan gambar kustom:
Menambahkan anotasi
Anotasi itu sendiri memiliki dua bagian:
- Objek
MKAnnotation
, yang mencakup data model tentang anotasi, seperti judul dan lokasi anotasi. MKAnnotationView
, yang berisi gambar untuk ditampilkan dan secara opsional callout yang ditampilkan saat pengguna mengetuk anotasi.
Map Kit menggunakan pola delegasi iOS untuk menambahkan anotasi ke peta, di mana Delegate
properti MKMapView
diatur ke instans MKMapViewDelegate
. Implementasi delegasi inilah yang bertanggung jawab untuk mengembalikan MKAnnotationView
anotasi.
Untuk menambahkan anotasi, pertama-tama anotasi ditambahkan dengan memanggil AddAnnotations
instans MKMapView
:
// add an annotation
map.AddAnnotations (new MKPointAnnotation (){
Title="MyAnnotation",
Coordinate = new CLLocationCoordinate2D (42.364260, -71.120824)
});
Ketika lokasi anotasi terlihat di peta, MKMapView
akan memanggil metode delegasinya GetViewForAnnotation
untuk mendapatkan tampilan MKAnnotationView
.
Misalnya, kode berikut mengembalikan yang disediakan MKPinAnnotationView
sistem :
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;
}
Penggunaan Kembali Anotasi
Untuk menghemat memori, MKMapView
memungkinkan tampilan anotasi dikumpulkan untuk digunakan kembali, mirip dengan cara sel tabel digunakan kembali. Mendapatkan tampilan anotasi dari kumpulan dilakukan dengan panggilan ke DequeueReusableAnnotation
:
MKAnnotationView pinView = (MKPinAnnotationView)mapView.DequeueReusableAnnotation (pId);
Menampilkan Callout
Seperti disebutkan sebelumnya, anotasi dapat secara opsional menampilkan callout. Untuk menampilkan callout, cukup atur CanShowCallout
ke true pada MKAnnotationView
. Ini menghasilkan judul anotasi yang ditampilkan saat anotasi diketuk, seperti yang ditunjukkan:
Menyesuaikan Callout
Callout juga dapat disesuaikan untuk menampilkan tampilan aksesori kiri dan kanan, seperti yang ditunjukkan di bawah ini:
pinView.RightCalloutAccessoryView = UIButton.FromType (UIButtonType.DetailDisclosure);
pinView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile ("monkey.png"));
Kode ini menghasilkan callout berikut:
Untuk menangani pengguna yang mengetuk aksesori yang tepat, cukup terapkan CalloutAccessoryControlTapped
metode di MKMapViewDelegate
:
public override void CalloutAccessoryControlTapped (MKMapView mapView, MKAnnotationView view, UIControl control)
{
...
}
Overlay
Cara lain untuk melapisi grafik pada peta adalah dengan menggunakan overlay. Overlay mendukung gambar konten grafis yang diskalakan dengan peta saat diperbesar. iOS menyediakan dukungan untuk beberapa jenis overlay, termasuk:
- Poligon - Umumnya digunakan untuk menyoroti beberapa wilayah di peta.
- Poliline - Sering terlihat saat menampilkan rute.
- Lingkaran - Digunakan untuk menyoroti area melingkar peta.
Selain itu, overlay kustom dapat dibuat untuk menampilkan geometri arbitrer dengan kode gambar granular dan disesuaikan. Misalnya, radar cuaca akan menjadi kandidat yang baik untuk overlay kustom.
Menambahkan Overlay
Mirip dengan anotasi, menambahkan overlay melibatkan 2 bagian:
- Membuat objek model untuk overlay dan menambahkannya ke
MKMapView
. - Membuat tampilan untuk overlay di
MKMapViewDelegate
.
Model untuk overlay dapat berupa subkelas apa pun MKShape
. Xamarin.iOS mencakup MKShape
subkelas untuk poligon, poliline, dan lingkaran, melalui MKPolygon
kelas , MKPolyline
dan MKCircle
masing-masing.
Misalnya, kode berikut digunakan untuk menambahkan MKCircle
:
var circleOverlay = MKCircle.Circle (mapCenter, 1000);
map.AddOverlay (circleOverlay);
Tampilan untuk overlay adalah MKOverlayView
instans yang dikembalikan oleh GetViewForOverlay
di MKMapViewDelegate
. Masing-masing MKShape
memiliki yang MKOverlayView
sesuai yang tahu cara menampilkan bentuk yang diberikan. Untuk MKPolygon
ada MKPolygonView
. Demikian pula, MKPolyline
sesuai dengan MKPolylineView
, dan untuk MKCircle
ada MKCircleView
.
Misalnya, kode berikut mengembalikan MKCircleView
untuk 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;
}
Ini menampilkan lingkaran pada peta seperti yang ditunjukkan:
Pencarian Lokal
iOS menyertakan API pencarian lokal dengan Map Kit, yang memungkinkan pencarian asinkron untuk tempat-tempat menarik di wilayah geografis tertentu.
Untuk melakukan pencarian lokal, aplikasi harus mengikuti langkah-langkah berikut:
- Buat
MKLocalSearchRequest
objek. - Buat
MKLocalSearch
objek dariMKLocalSearchRequest
. Start
Panggil metode padaMKLocalSearch
objek .MKLocalSearchResponse
Ambil objek dalam panggilan balik.
API pencarian lokal itu sendiri tidak menyediakan antarmuka pengguna. Bahkan tidak memerlukan peta untuk digunakan. Namun, untuk memanfaatkan pencarian lokal secara praktis, aplikasi perlu menyediakan beberapa cara untuk menentukan kueri pencarian dan menampilkan hasil. Selain itu, karena hasilnya akan berisi data lokasi, sering kali masuk akal untuk menampilkannya di peta.
Menambahkan antarmuka pengguna Pencarian Lokal
Salah satu cara untuk menerima input pencarian adalah dengan UISearchBar
, yang disediakan oleh UISearchController
dan akan menampilkan hasil dalam tabel.
Kode berikut menambahkan UISearchController
(yang memiliki properti bilah pencarian) dalam ViewDidLoad
metode 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;
Perhatikan bahwa Anda bertanggung jawab untuk memasukkan objek bilah pencarian ke dalam antarmuka pengguna. Dalam contoh ini, kami menetapkannya ke TitleView bilah navigasi, tetapi jika Anda tidak menggunakan pengontrol navigasi di aplikasi Anda, Anda harus menemukan tempat lain untuk menampilkannya.
Dalam cuplikan kode ini, kami membuat pengontrol tampilan kustom lain - searchResultsController
yang menampilkan hasil pencarian dan kemudian kami menggunakan objek ini untuk membuat objek pengontrol pencarian kami. Kami juga membuat pembaruan pencarian baru, yang menjadi aktif ketika pengguna berinteraksi dengan bilah pencarian. Ini menerima pemberitahuan tentang pencarian dengan setiap penekanan tombol dan bertanggung jawab untuk memperbarui UI.
Kami akan melihat cara mengimplementasikan dan searchResultsController
nanti searchResultsUpdater
dalam panduan ini.
Ini menghasilkan bilah pencarian yang ditampilkan di atas peta seperti yang ditunjukkan di bawah ini:
Menampilkan Hasil Pencarian
Untuk menampilkan hasil pencarian, kita perlu membuat Pengontrol Tampilan kustom; biasanya .UITableViewController
Seperti yang searchResultsController
ditunjukkan di atas, diteruskan ke konstruktor searchController
saat sedang dibuat.
Kode berikut adalah contoh cara membuat Pengontrol Tampilan kustom ini:
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);
}
});
}
}
Memperbarui Hasil Pencarian
Bertindak SearchResultsUpdater
sebagai mediator antara bilah searchController
pencarian dan hasil pencarian.
Dalam contoh ini kita harus terlebih dahulu membuat metode pencarian di SearchResultsViewController
. Untuk melakukan ini, kita harus membuat MKLocalSearch
objek dan menggunakannya untuk mengeluarkan pencarian MKLocalSearchRequest
, hasilnya diambil dalam panggilan balik yang diteruskan ke Start
metode MKLocalSearch
objek. Hasilnya kemudian dikembalikan dalam objek yang MKLocalSearchResponse
berisi array MKMapItem
objek:
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);
}
});
}
Kemudian, di kami, kami MapViewController
akan membuat implementasi UISearchResultsUpdating
kustom , yang ditetapkan ke SearchResultsUpdater
properti kami searchController
di bagian Menambahkan UI Pencarian Lokal:
public class SearchResultsUpdator : UISearchResultsUpdating
{
public event Action<string> UpdateSearchResults = delegate {};
public override void UpdateSearchResultsForSearchController (UISearchController searchController)
{
this.UpdateSearchResults (searchController.SearchBar.Text);
}
}
Implementasi di atas menambahkan anotasi ke peta saat item dipilih dari hasil, seperti yang ditunjukkan di bawah ini:
Penting
UISearchController
diimplementasikan di iOS 8. Jika Anda ingin mendukung perangkat lebih awal dari ini, maka Anda harus menggunakan UISearchDisplayController
.
Ringkasan
Artikel ini memeriksa kerangka kerja MapKit untuk iOS. Pertama, ia melihat bagaimana MKMapView
kelas memungkinkan peta interaktif untuk disertakan dalam aplikasi. Kemudian menunjukkan cara menyesuaikan peta lebih lanjut menggunakan anotasi dan overlay. Akhirnya, ia memeriksa kemampuan pencarian lokal yang ditambahkan ke Map Kit dengan iOS 6.1, yang menunjukkan cara menggunakan melakukan kueri berbasis lokasi untuk tempat menarik dan menambahkannya ke peta.