How to Show Userlocation Swift Mapkit Blue Dot

RRS feed

  • Remove From My Forums

 locked

MKMapView .ShowsUserLocation - not displaying blue dot RRS feed

  • Question

  • User125 posted

    I'm running in the stable channel. I went through the process of updating to the Unified API on Monday. I'm getting a report that our MKMapView is not displaying the blue dot designating the user location. I have the .ShowsUserLocation property set to true on the mapview. Any thoughts on this?

All replies

  • User125 posted

    Ok, so I realize why I'm not displaying the blue dot (dumb me). I have the GetViewForAnnotation set to the method below. I'm trying to get the blue dot for the current location, a step of pins for several points, and to be able to act when the user selects a point. I thought that first if statement would keep a pin from being placed on the user's location and would give me the blue dot. I assume that this is something I am doing, but am a bit lost on what I should be checking for. Suggestions are appreciated.

                                              MKAnnotationView ViewForAnnotation(MKMapView mapView, IMKAnnotation annotation) {            if (annotation == map.UserLocation)            {               return null;           }           // ObjAnnotation myAnn = annotation as ObjAnnotation;           var annView = mapView.DequeueReusableAnnotation ("pin");           if (annView == null) {               MKPinAnnotationView customPinView = new MKPinAnnotationView (annotation, "pin");               //customPinView.PinColor = MKPinAnnotationColor.Purple;               customPinView.AnimatesDrop = true;               customPinView.CanShowCallout = true;               UIButton rightButton = UIButton.FromType (UIButtonType.DetailDisclosure);               customPinView.RightCalloutAccessoryView = rightButton;               pinViews.Add(customPinView);               Console.WriteLine(String.Format("Description: {0}", customPinView.Description));               return customPinView;           }           else            {               annView.Annotation = annotation;           }           return annView;       }                                      
  • User78315 posted

    Hi!

    Had the same problem...

    I added the ask for location key in info.plist.

    location NSLocationUsageDescription paraMobile möchte Ihren aktuellen Standort verwenden. NSLocationAlwaysUsageDescription paraMobile möchte Ihren aktuellen Standort verwenden. NSLocationWhenInUseUsageDescription paraMobile möchte Ihren aktuellen Standort.

    This solved my problems.. And the pin was there.

    Set in MapView ShowsUserLocation to True.

    Regards, Jörg

  • User1669 posted

    Hi Wally, I'm running into the same issue as well, and have tracked down the reason, but have yet to find a solution. In my code I had:

                        if (annotation is MKUserLocation) {   return null; }                                      

    This used to work, and the blue dot would appear, but now it doesn't work. The reason is because the Annotation type has changed (when it is the current location) from MKUserLocation to MKAnnotationWrapper. MKAnnotationWrapper seems to be a private class, and not accessible. So checking to see if it is type MKAnnotationWrapper will produce a compile error.

    I also suspect that's why your code is failing also:

                        if (annotation == map.UserLocation)    {      return null;   }                                      

    map.UserLocation is of type MKUserLocation, and annotation is of type MKAnnotationWrapper. If I find a solution, I'll let you know.

  • User125 posted

    Thanks @rmacias. I had the "annotation is MKUserLocation" in the test of my if clause previous and was just trying to use something that looked a bit more like a location or an annotation. Neither seemed to be possible, so I just left it.

  • User1669 posted

    @wallym? Okay, I think I got it. This seems to be working for me. Though it still seems awkward to me, but it works for now.

                        var currentLocation = mapView.UserLocation.Coordinate; var annotationLocation = annotation.Coordinate;  if (currentLocation.Latitude == annotationLocation.Latitude && currentLocation.Longitude == annotationLocation.Longitude) {     return null; }                                      
  • User125 posted

    @rmacias Thanks. I was thinking of something similar. Just feels weird. :-)

  • User1669 posted

    Right! I know the feeling. I have a feeling I'll be addressing this again when the iOS 9 SDK is released.

  • User94 posted

    I had the same problem, and the way I solved it (not saying it is the best way but it works for me) is the following.

                                              _mapView.DidAddAnnotationViews += (object sender, MKMapViewAnnotationEventArgs e) => {             foreach (MKAnnotationView av in e.Views) {                 if (av.RightCalloutAccessoryView == null) {                     av.CanShowCallout = false;                     av.Enabled = false;                 }             }         };                                      

    I need to make sure the blue dot was not selectable so checked for the RightCalloutAccessoryView which I set for every other annotation so it finds the blue dot, of course you need to modify to make it work for you.

    atb

    alex

  • User65001 posted

    Hi there, first thank you Ruben for the fix. But MKUserLocation should inherit IMKAnnotation, shouldn't it?? The whole hierarchy of PinPointAnnotations and MKAnnotations feels a little bit clumsy. An thoughts here?

    Kind regards,

    Markus

  • User31385 posted

    This feels like a bug in Xamarin's Obj-C wrappers to me. I'm trying to create a custom view for each map annotation, and IMKAnnotation now doesn't cast correctly (at runtime) to my MKPointAnnotation subclass. It complains instead that it can't cast a MKAnnotationWrapper to the subclass, when clearly it should be able to do so. This is unfortunate as it's totally broken an app I'm working on. Any bright ideas for a solution would be much appreciated.

  • User1669 posted

    @wallym?, @MarkusSchiller?, @DavidDancy?,

    I think I have a sensible solution now. First, it seems that this is by design, and Rolf explains why this is the case here:

    https://bugzilla.xamarin.com/show_bug.cgi?id=26416#c1

    Using his suggestion, I've implemented the following code, and have confirmed it works as it did previously.

                        public override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation) {       if(ThisIsTheCurrentLocation(mapView, annotation))       {           return null;       }        var view = mapView.DequeueReusableAnnotation(_pinId) as MKAnnotationView ?? new MKAnnotationView(annotation, _pinId);        view.Image = UIImage.FromBundle("CustomPinImage");       view.CanShowCallout = true;       view.RightCalloutAccessoryView = UIButton.FromType(UIButtonType.InfoLight);        return view; }  private bool ThisIsTheCurrentLocation(MKMapView mapView, IMKAnnotation annotation) {       var userLocationAnnotation = ObjCRuntime.Runtime.GetNSObject(annotation.Handle) as MKUserLocation;       if(userLocationAnnotation != null)       {           return userLocationAnnotation == mapView.UserLocation;       }        return false; }                                      

    Hope this helps!

  • User31385 posted

    Thank you - I'll give it a try.

  • User65001 posted

    Hi, very interesting - thank you. Sometimes its good to remember that its Objective-C behind the scenes.

  • User16250 posted

    Thanks for your code snippets guys. Got the same issues with user location in MKMap after upgrading to Unified API and this thread helped to fix it!

    I believe everybody who uses MKMap in their apps would get it, so maybe we need to request Xamarin guys to add this into the Guide http://developer.xamarin.com/guides/cross-platform/macios/updating-tips/ ?

  • User80559 posted

    https://bugzilla.xamarin.com/show_bug.cgi?id=26416#c1

                        public override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)     {          if (annotation.GetType().ToString() == "MapKit.MKAnnotationWrapper") //which means is MKUserLocation             return null; //...  //Manage other annotations as MKPinAnnotationView   }                                      
  • User214804 posted

    Hi ,below is my code using System; using System.Collections.Generic; using CoreGraphics; using HomeRecyclingTruck.iOS; using MapKit; using UIKit; using Xamarin.Forms; using Xamarin.Forms.Maps; using Xamarin.Forms.Maps.iOS; using Xamarin.Forms.Platform.iOS; using CoreLocation; using HomeRecyclingTruck.Models; using System.Globalization;

    [assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))] namespace HomeRecyclingTruck.iOS { public class CustomMapRenderer : MapRenderer { List customPins; MKPolylineRenderer polylineRenderer; List> routeCoordinates;

                                              CLLocationManager locMgr = new CLLocationManager();      protected override void Dispose(bool disposing)     {         base.Dispose(disposing);     }     protected override void OnElementChanged(ElementChangedEventArgs<View> e)     {         base.OnElementChanged(e);          if (e.OldElement != null)         {             //Varun1             //Used for initialisation              var nativeMap = Control as MKMapView;             nativeMap.OverlayRenderer = null;             nativeMap.GetViewForAnnotation = null;             nativeMap.DidSelectAnnotationView -= OnDidSelectAnnotationView;             nativeMap.DidDeselectAnnotationView -= OnDidDeselectAnnotationView;             nativeMap.Dispose();          }          if (e.NewElement != null)         {             var formsMap = (CustomMap)e.NewElement;             var nativeMap = Control as MKMapView;               customPins = formsMap.CustomPins;              nativeMap.OverlayRenderer = GetOverlayRenderer;             nativeMap.GetViewForAnnotation = GetViewForAnnotation;             nativeMap.DidSelectAnnotationView += OnDidSelectAnnotationView;             nativeMap.DidDeselectAnnotationView += OnDidDeselectAnnotationView;              routeCoordinates = formsMap.RouteCoordinates;              int ArrayCount = 0;              for (int i = 0; i < routeCoordinates.Count; i++)             {                 ArrayCount = ArrayCount + routeCoordinates[i].Count;             }               CLLocationCoordinate2D[] coords = new CLLocationCoordinate2D[ArrayCount];             int index = 0;              for (int i = 0; i < routeCoordinates.Count; i++)             {                   for (int j = 0; j < routeCoordinates[i].Count; j++)                 {                     coords[index] = new CLLocationCoordinate2D(double.Parse(routeCoordinates[i][j].latitude, CultureInfo.InvariantCulture), double.Parse(routeCoordinates[i][j].longitude, CultureInfo.InvariantCulture));                      index++;                 }              }              var routeOverlay = MKPolyline.FromCoordinates(coords);             nativeMap.AddOverlay(routeOverlay);               if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))             {                  locMgr.RequestWhenInUseAuthorization(); // only in foreground                 locMgr.StartUpdatingLocation();                 //nativeMap.ShowsUserLocation = true;             }           }     }      MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlay)     {         if (overlay != null)         {             var o = ObjCRuntime.Runtime.GetNSObject(overlay.Handle) as IMKOverlay;             if (polylineRenderer == null)             {                  polylineRenderer = new MKPolylineRenderer(o as MKPolyline);                 polylineRenderer.FillColor = UIColor.Blue;                 polylineRenderer.StrokeColor = UIColor.Red;                 polylineRenderer.LineWidth = 3;                 polylineRenderer.Alpha = 0.4f;             }         }            return polylineRenderer;     }       MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)     {         MKAnnotationView annotationView = null;          if (annotation is MKUserLocation)             return null;          var anno = annotation as MKPointAnnotation;         var customPin = GetCustomPin(anno);         if (customPin == null)         {             throw new Exception("Custom pin not found");         }          annotationView = mapView.DequeueReusableAnnotation(customPin.Id);            if (annotationView == null)         {             annotationView = new CustomMKAnnotationView(annotation, customPin.Id);              if (customPin.Id == "Origin")             {                 annotationView.Image = UIImage.FromFile("AppIcon/OriginPin.png");             }             else             {                 if (customPin.Id == "Destination")                 {                     annotationView.Image = UIImage.FromFile("AppIcon/DestinationPin.png");                 }                 else                 {                     if (customPin.Id == "Upcoming")                     {                         annotationView.Image = UIImage.FromFile("AppIcon/UpcomingPin.png");                     }                     else                     {                         annotationView.Image = UIImage.FromFile("AppIcon/CompletedPin.png");                     }                 }             }              //annotationView.Image = UIImage.FromFile(Utility.ImagePath.logout);             annotationView.CalloutOffset = new CGPoint(0, 0);         }         annotationView.CanShowCallout = true;          return annotationView;     }      void OnDidSelectAnnotationView(object sender, MKAnnotationViewEventArgs e)     {      }      void OnDidDeselectAnnotationView(object sender, MKAnnotationViewEventArgs e)     {      }        CustomPin GetCustomPin(MKPointAnnotation annotation)     {         var position = new Position(annotation.Coordinate.Latitude, annotation.Coordinate.Longitude);         foreach (var pin in customPins)         {             if (pin.Pin.Position == position)             {                 return pin;             }         }         return null;     } }                                      

    }

    which is used to display map with routes when i set nativeMap.ShowsUserLocation = true; app gets crashed with following error ERROR /BuildRoot/Library/Caches/com.apple.xbs/Sources/VectorKit/VectorKit-1228.30.7.17.9/GeoGL/GeoGL/GLCoreContext.cpp 1763: InfoLog SolidRibbonShader: ERROR /BuildRoot/Library/Caches/com.apple.xbs/Sources/VectorKit/VectorKit-1228.30.7.17.9/GeoGL/GeoGL/GLCoreContext.cpp 1764: WARNING: Output of vertex shader 'v_gradient' not read by fragment shader

    if i remove same app is working fine,Could some one help me to show user location

washingtongise1957.blogspot.com

Source: https://social.msdn.microsoft.com/Forums/en-US/xamarinThread/30843/mkmapview-showsuserlocation-not-displaying-blue-dot

0 Response to "How to Show Userlocation Swift Mapkit Blue Dot"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel