Xamarin.iOS: MapView Recipe

In this article, which is the first article on Xamarin.iOS Application development series, we will see how we use the MapView control. We will be describing briefly about the MapView and talk about some common methods and properties which are very beneficial and mandatory.

Ingredients

  • Visual Studio 2012 or higher / Xamarin Studio 5
  • Xamarin iOS 6.4.5 or higher
  • Mac OS X Yosemite(10.10) & above.

Procedure

  1. Create a new application in Xamarin Studio by selecting New Solution from the Welcome screen.



  2. Select iOS App from the installed templates. Now, as you can see we have a lot of options, like Single View App, Master-Detail App, Tabbed App. These are nothing but pre-defined UI screens for the ease-of-use for the developers. For this tutorial, we will select Single View App.



  3. Now, you can see that the solution file is created and it contains all the required files, as shown in the figure below:



  4. Now, we will open ViewController.cs from the Solution and import MapKit, CoreLocation and CoreGraphics. 
    1. using MapKit;  
    2. using CoreLocation;  
    3. using CoreGraphics;  
  5. Create objects of MapView, UISegmentedControl (we will be using this to toggle between map types), and CLLocationManager, in the ViewController class.
    1. MKMapView mapView;  
    2. UISegmentedControl mapTypeSelection;  
    3. CLLocationManager location = new CLLocationManager();  
  6. To set the title of the app in the ViewDidLoad function, just write: 
    1. public override void ViewDidLoad ()  
    2. {  
    3. base.ViewDidLoad ();  
    4. // Perform any additional setup after loading the view, typically from a nib.  
    5. Title = "Map View Sample";  
    6. }  
  7. Now, we will add the MapView properties in the ViewDidLoad function to request user permission, to show user location and to toggle between map types. Also, add the MapView and the UISegmentedControl to the View:
    1. mapView = new MKMapView(View.Bounds);  
    2. mapView.AutoresizingMask = UIViewAutoresizing.FlexibleDimensions;  
    3. View.AddSubview(mapView);  
    4. // Request permission to access device location  
    5. location.RequestWhenInUseAuthorization();  
    6. // Indicates User Location  
    7. mapView.ShowsUserLocation = true;  
    8. //This snippet lets you toggle between Map Types  
    9. int typesWidth=260, typesHeight=30, distanceFromBottom=60;  
    10. mapTypeSelection = new UISegmentedControl(new CGRect((View.Bounds.Width-typesWidth)/2, View.Bounds.Height-distanceFromBottom, typesWidth, typesHeight));  
    11. mapTypeSelection.InsertSegment("Standard", 0, false);  
    12. mapTypeSelection.InsertSegment("Satellite", 1, false);  
    13. mapTypeSelection.InsertSegment("Hybrid", 2, false);  
    14. mapTypeSelection.SelectedSegment = 0; // Standard is the default selection  
    15. mapTypeSelection.AutoresizingMask = UIViewAutoresizing.FlexibleTopMargin;  
    16. mapTypeSelection.ValueChanged += (s, e) => {  
    17. switch(mapTypeSelection.SelectedSegment) {  
    18. case 0:  
    19. mapView.MapType = MKMapType.Standard;  
    20. break;  
    21. case 1:  
    22. mapView.MapType = MKMapType.Satellite;  
    23. break;  
    24. case 2:  
    25. mapView.MapType = MKMapType.Hybrid;  
    26. break;  
    27. }  
    28. };  
    29. View.AddSubview(mapTypeSelection);  
  8. Now, we will add the following code snippet to set the co-ordinates for the map to zoom at:
    1. mapView.DidUpdateUserLocation += (sender, e) => {  
    2. if (mapView.UserLocation != null) {  
    3. CLLocationCoordinate2D coords = mapView.UserLocation.Coordinate;  
    4. MKCoordinateSpan span = new MKCoordinateSpan(MilesToLatitudeDegrees(2), MilesToLongitudeDegrees(2, coords.Latitude));  
    5. mapView.Region = new MKCoordinateRegion(coords, span);  
    6. }  
    7. };  
    8. if (!mapView.UserLocationVisible) {  
    9. // User denied permission or device doesn't have GPS/location ability  
    10. // create our location and zoom to Chicago  
    11. CLLocationCoordinate2D coords = new CLLocationCoordinate2D(41.8781, -87.6298); // Chicago  
    12. MKCoordinateSpan span = new MKCoordinateSpan(MilesToLatitudeDegrees(20), MilesToLongitudeDegrees(20, coords.Latitude));  
    13. // set the coords and zoom on the map  
    14. mapView.Region = new MKCoordinateRegion(coords, span);  
    15. }  
  9. Finally, our ViewDidLoad() will look something like this:
    1. public override void ViewDidLoad ()  
    2. {  
    3. base.ViewDidLoad ();  
    4. // Perform any additional setup after loading the view, typically from a nib.  
    5. Title = "Map View Sample";  
    6. mapView = new MKMapView(View.Bounds);  
    7. mapView.AutoresizingMask = UIViewAutoresizing.FlexibleDimensions;  
    8. View.AddSubview(mapView);  
    9. // Request permission to access device location  
    10. location.RequestWhenInUseAuthorization();  
    11. // Indicates User Location  
    12. mapView.ShowsUserLocation = true;  
    13. //This snippet lets you toggle between Map Types  
    14. int typesWidth=260, typesHeight=30, distanceFromBottom=60;  
    15. mapTypeSelection = new UISegmentedControl(new CGRect((View.Bounds.Width-typesWidth)/2, View.Bounds.Height-distanceFromBottom, typesWidth, typesHeight));  
    16. mapTypeSelection.InsertSegment("Standard", 0, false);  
    17. mapTypeSelection.InsertSegment("Satellite", 1, false);  
    18. mapTypeSelection.InsertSegment("Hybrid", 2, false);  
    19. mapTypeSelection.SelectedSegment = 0; // Standard is the default selection  
    20. mapTypeSelection.AutoresizingMask = UIViewAutoresizing.FlexibleTopMargin;  
    21. mapTypeSelection.ValueChanged += (s, e) => {  
    22. switch(mapTypeSelection.SelectedSegment) {  
    23. case 0:  
    24. mapView.MapType = MKMapType.Standard;  
    25. break;  
    26. case 1:  
    27. mapView.MapType = MKMapType.Satellite;  
    28. break;  
    29. case 2:  
    30. mapView.MapType = MKMapType.Hybrid;  
    31. break;  
    32. }  
    33. };  
    34. View.AddSubview(mapTypeSelection);  
    35. mapView.DidUpdateUserLocation += (sender, e) => {  
    36. if (mapView.UserLocation != null) {  
    37. CLLocationCoordinate2D coords = mapView.UserLocation.Coordinate;  
    38. MKCoordinateSpan span = new MKCoordinateSpan(MilesToLatitudeDegrees(2), MilesToLongitudeDegrees(2, coords.Latitude));  
    39. mapView.Region = new MKCoordinateRegion(coords, span);  
    40. }  
    41. };  
    42. if (!mapView.UserLocationVisible) {  
    43. // User denied permission or device doesn't have GPS/location ability  
    44. // create our location and zoom to Chicago  
    45. CLLocationCoordinate2D coords = new CLLocationCoordinate2D(41.8781, -87.6298); // Chicago  
    46. MKCoordinateSpan span = new MKCoordinateSpan(MilesToLatitudeDegrees(20), MilesToLongitudeDegrees(20, coords.Latitude));  
    47. // set the coords and zoom on the map  
    48. mapView.Region = new MKCoordinateRegion(coords, span);  
    49. }  
    50. }  
  10. Now, let's add the helper methods which we have used to calculate the area to show on the map:
    1. public double MilesToLatitudeDegrees(double miles)  
    2. {  
    3. double earthRadius = 3960.0; // in miles  
    4. double radianToDegree = 180.0/Math.PI;  
    5. return (miles/earthRadius) * radianToDegree;  
    6. }  
    7. public double MilesToLongitudeDegrees(double miles, double atLatitude)  
    8. {  
    9. double earthRadius = 3960.0; // in miles  
    10. double degreeToRadian = Math.PI/180.0;  
    11. double radianToDegree = 180.0/Math.PI;  
    12. // derive the earth's radius at that point in latitude  
    13. double radiusAtLatitude = earthRadius * Math.Cos(atLatitude * degreeToRadian);  
    14. return (miles / radiusAtLatitude) * radianToDegree;  
    15. }  
  11. Now, we run the app on the iPhone simulator of our choice (i did it on iPhone 6S) and it look likes this,

Make some beautiful apps using Xamarin.iOS and tweet your queries to @adiiaditya. If you want to fork this project, visit my Git.


Similar Articles