Forum Xamarin.Forms

Custom Pins(Annotations) xamarin forms ios not changed on version below 14.

Hello. I created renderer of the map for customizing my pins. (Use "Xamarin.Forms.Maps.iOS")

"GetViewForAnnotation":

protected override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
        {
            MKAnnotationView annotationView = base.GetViewForAnnotation(mapView, annotation);

            if (annotation is MKUserLocation)
                return null;

            if (annotationView is MKPinAnnotationView pinView)
            {
                var pins = ((Map)Element).Pins;

                var selectedPin = (RoutePin)pins.FirstOrDefault(x => (x as RoutePin).MarkerId == annotation);

                if (selectedPin != null)
                {
                    pinView.Image = CreatePinBitmap(selectedPin.OrderNumber.ToString(),
                        UIColor.FromRGB(selectedPin.BackgroundColor.R, selectedPin.BackgroundColor.G,
                            selectedPin.BackgroundColor.B));
                }
            }
            return annotationView;
        }

"CreatePinBitmap":

private UIImage CreatePinBitmap(string orderText, UIColor bgColor)
        {
            float outerCircleSize = 20;
            float innerCircleSize = 14;            

            var pinSize = new CGSize(20, 38);
            var pointerSize = new CGSize(10, 14);

            var mainImageRenderer = new UIGraphicsImageRenderer(pinSize);
            var outerCircleImageRenderer = new UIGraphicsImageRenderer(new CGSize(outerCircleSize, outerCircleSize));
            var innerCircleImageRenderer = new UIGraphicsImageRenderer(new CGSize(innerCircleSize, innerCircleSize));
            var pointerImageRenderer = new UIGraphicsImageRenderer(pointerSize);

            var outerCircle = outerCircleImageRenderer.CreateImage((x) =>
            {
                var circleRect = new CGRect(0, 0, outerCircleSize, outerCircleSize);

                x.CGContext.SetFillColor(bgColor.CGColor);
                x.CGContext.FillEllipseInRect(circleRect);
                x.CGContext.SetStrokeColor(bgColor.CGColor);
                x.CGContext.DrawPath(CGPathDrawingMode.Fill);
            });
            var innerCircle = innerCircleImageRenderer.CreateImage((x) =>
            {
                var circleRect = new CGRect(0, 0, innerCircleSize, innerCircleSize);

                x.CGContext.SetFillColor(UIColor.White.CGColor);
                x.CGContext.FillEllipseInRect(circleRect);
                x.CGContext.SetStrokeColor(UIColor.White.CGColor);
                x.CGContext.DrawPath(CGPathDrawingMode.Fill);
            });
            var pointer = innerCircleImageRenderer.CreateImage((x) =>
            {
                var pointerPath = new CGPath();
                pointerPath.AddLines(new CGPoint[] {new CGPoint(0, 0), new CGPoint(pointerSize.Width, 0),  new CGPoint(pointerSize.Width / 2, pointerSize.Height) });

                x.CGContext.SetFillColor(bgColor.CGColor);//bgColor.CGColor);
                x.CGContext.SetStrokeColor(bgColor.CGColor);
                x.CGContext.AddPath(pointerPath);
                x.CGContext.DrawPath(CGPathDrawingMode.Fill);
            });

            var pin = mainImageRenderer.CreateImage((x) =>
            {
                var outerCircleRect = new CGRect(0, 0, outerCircleSize, outerCircleSize);
                var innerCircleRect = new CGRect(3, 3, innerCircleSize, innerCircleSize);
                var pointerRect = new CGRect(6.5, 16, pointerSize.Width, pointerSize.Height);

                outerCircle.Draw(outerCircleRect, CGBlendMode.Normal, 1);
                pointer.Draw(pointerRect, CGBlendMode.Normal, 1);
                innerCircle.Draw(innerCircleRect, CGBlendMode.Normal, 1);
            });

            return pin;
        }

It's works great. But. On the version iOS 14. I.e. I tested on 11.4, 12.4.9 and 14.4. Only on 14.4 version, my pins look correctly.

Mb who has info? Help me, plz.

Best Answer

  • DeathgarDeathgar Member ✭✭
    edited February 23 Accepted Answer

    I changed GetViewForAnnotation. I changed the pins incorrectly. Partially incorrect.

    New method:

    private MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
            {
                MKAnnotationView annotationView = mapView.DequeueReusableAnnotation(annotationId);
    
                if (IsUserLocation(mapView, annotation))
                    return null;
    
                if (annotationView == null)
                {
                    var pins = ((Map)Element).Pins;
    
                    var selectedPin = (RoutePin)pins.FirstOrDefault(x => (x as RoutePin).MarkerId == annotation);
    
                    annotationView = new MKAnnotationView(annotation, annotationId);
                        annotationView.Image = CreatePinBitmap(selectedPin.OrderNumber.ToString(),
                            UIColor.FromRGB(selectedPin.BackgroundColor.R, selectedPin.BackgroundColor.G,
                                selectedPin.BackgroundColor.B));
    
                }
    
                return annotationView;
            } 
    

Answers

  • ColeXColeX Member, Xamarin Team Xamurai

    For this issue only happens on some specific versions, I suggest you raise issue on github : https://github.com/xamarin/Xamarin.Forms/issues.


    Xamarin forums are migrating to a new home on Microsoft Q&A!
    We invite you to post new questions in the Xamarin forums’ new home on Microsoft Q&A!
    For more information, please refer to this sticky post.

  • DeathgarDeathgar Member ✭✭
    edited February 23 Accepted Answer

    I changed GetViewForAnnotation. I changed the pins incorrectly. Partially incorrect.

    New method:

    private MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
            {
                MKAnnotationView annotationView = mapView.DequeueReusableAnnotation(annotationId);
    
                if (IsUserLocation(mapView, annotation))
                    return null;
    
                if (annotationView == null)
                {
                    var pins = ((Map)Element).Pins;
    
                    var selectedPin = (RoutePin)pins.FirstOrDefault(x => (x as RoutePin).MarkerId == annotation);
    
                    annotationView = new MKAnnotationView(annotation, annotationId);
                        annotationView.Image = CreatePinBitmap(selectedPin.OrderNumber.ToString(),
                            UIColor.FromRGB(selectedPin.BackgroundColor.R, selectedPin.BackgroundColor.G,
                                selectedPin.BackgroundColor.B));
    
                }
    
                return annotationView;
            } 
    
Sign In or Register to comment.