How to Show Userlocation Swift Mapkit Blue Dot
- Remove From My Forums
-
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
MKUserLocationtoMKAnnotationWrapper.MKAnnotationWrapperseems to be a private class, and not accessible. So checking to see if it is typeMKAnnotationWrapperwill produce a compile error.I also suspect that's why your code is failing also:
if (annotation == map.UserLocation) { return null; }map.UserLocationis of typeMKUserLocation, and annotation is of typeMKAnnotationWrapper. 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
IMKAnnotationnow doesn't cast correctly (at runtime) to myMKPointAnnotationsubclass. It complains instead that it can't cast aMKAnnotationWrapperto 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