Search code examples
iosxamarin.formscustom-renderer

Icon with padding and rounded corners - iOS Custom Renderer for Xamarin Forms


I'm trying to create an image with rounded corners and ass 5pts of padding around the image. I've got the corners working, but the image, an icon, takes up the entire control. Some things that I've tried are:

    public override void LayoutSubviews()
    {
        try
        {
            var element = (IconTile)Element;
            var textheight = element.HeightRequest / 3;

            Control.Layer.CornerRadius = 10;
            Control.Layer.BackgroundColor = HelperUtilities.GetColor(element.Item.BackgroundColor, Color.Transparent).ToCGColor();
            Control.ClipsToBounds = true;

            //Control.Image.Scale(new CGSize(element.WidthRequest - 10, element.HeightRequest - 10));
            Control.Image = Control.Image.ImageWithAlignmentRectInsets(new UIEdgeInsets(5, 5, 5, 5));
            Control.Frame = new CGRect(5, 5, element.Width - 10, element.Height - 10);
            Control.LayoutMargins = new UIEdgeInsets(5,5,5,5);
            Control.Image.DrawAsPatternInRect(new CGRect(5, 5, element.Width - 10, element.Height - 10));
            //UIGraphics.BeginImageContextWithOptions(new CGSize(element.WidthRequest - 40, element.HeightRequest - 40), false, 0f);
            base.LayoutSubviews();

In Android I was able to do this using

            child.SetPadding(20,20,20,20);
            var result = base.DrawChild(canvas, child, drawingTime);

How do I do this in iOS?

It looks like in iOS I should be able to do this by setting the Frame on the control like this:

            CGSize size = Control.Image.Size;
            CGRect rect = new CGRect(0, 0, size.Width - 5, size.Height - 5);
            Control.Frame = rect;

taken from https://stackoverflow.com/a/6435536/1181230. But the image size is now adjusted to the frame. Is this a bug in Forms?


Solution

  • I ended up overriding TrySetImage and called my own SetImage, which creates a new imageview with a frame .. I replaced:

                var imageView = Control;
                if (imageView != null)
                    imageView.Image = uiimage;
    

    with:

                var imageOnly = ((IconTile) Element).ImageOnly;
                _imageView = new UIImageView(imageOnly ? new CGRect(7, 7, Element.WidthRequest - 14, Element.HeightRequest - 14)
                    : new CGRect(10, 10, Element.WidthRequest - 20, Element.HeightRequest - 20))
                {
                    Image = uiimage,
                    ClipsToBounds = true,
                };
                Control.InsertSubview(_imageView, 0);