65.9K
CodeProject is changing. Read more.
Home

Xamarin.Forms Circle Image for iOS

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.21/5 (6 votes)

Oct 25, 2014

CPOL
viewsIcon

26670

Xamarin.Forms Circle image for iOS

Introduction

Xamarin.Forms circle shaped image!

Background

I've been searching for this for a long time, then I decided to make my own. Feel free to use it.

Using the Code

Just put the class in the shared project, and the renderer in the iOS project.

The Renderer

using System;
using Xamarin.Forms;
using MonoTouch.UIKit;
using Xamarin.Forms.Platform.iOS;
using System.Drawing;
using RBVRenderer;
using RBVRenderer.iOS;

[assembly: ExportRendererAttribute(typeof(CircleImage), typeof(CircleImageRenderer))]
namespace RBVRenderer.iOS
{

    public class CircleImageRenderer : ViewRenderer<CircleImage,UIView>
    {
        UIImageView imageView;
        protected override void OnElementChanged(ElementChangedEventArgs<CircleImage> e)
        {
            base.OnElementChanged(e);

            var rbv = e.NewElement;
            if (rbv != null) {

                var mainView = new UIView();

                imageView = new UIImageView (UIImage.FromBundle(rbv.FileSource));
                imageView.Frame = new RectangleF 
                (0, 0, (float)rbv.WidthRequest, (float)rbv.HeightRequest);
                imageView.Layer.CornerRadius = imageView.Frame.Size.Width / 2;
                if (rbv.HasBorder) {
                    imageView.Layer.BorderColor = rbv.BorderColor.ToCGColor();
                    imageView.Layer.BorderWidth = 2;
                }
                imageView.ClipsToBounds = true;

                mainView.Add (imageView);

                SetNativeControl(mainView);
            }
        }

        protected override void OnElementPropertyChanged
        (object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName == CircleImage.HasBorderProperty.PropertyName) {
                if (Element.HasBorder) {
                    imageView.Layer.BorderWidth = 2;
                    imageView.Layer.BorderColor = this.Element.BorderColor.ToCGColor ();
                } else {
                    imageView.Layer.BorderWidth = 0;
                }
            }
        }
    }
}

The Class

using System;
using Xamarin.Forms;

namespace RBVRenderer
{
    public class CircleImage : Image
    {
        public static readonly BindableProperty FileSourceProperty =
            BindableProperty.Create<CircleImage, string>(p => p.FileSource, "");

        /// <summary>
        /// string filename
        /// </summary>
        /// <value>The source.</value>
        public string FileSource
        {
            get { return (string)base.GetValue(FileSourceProperty);}
            set { base.SetValue(FileSourceProperty, value);}
        }

        public static readonly BindableProperty BorderColorProperty =
            BindableProperty.Create<CircleImage, Color>(p => p.BorderColor, Color.White);

        public Color BorderColor
        {
            get { return (Color)base.GetValue(BorderColorProperty);}
            set { base.SetValue(BorderColorProperty, value);}
        }

        public static readonly BindableProperty HasBorderProperty =
            BindableProperty.Create<CircleImage, bool>(p => p.HasBorder, false);

        public bool HasBorder
        {
            get { return (bool)base.GetValue(HasBorderProperty);}
            set { base.SetValue(HasBorderProperty, value);}
        }
    }
}

Usage

<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:me="clr-namespace:RBVRenderer;assembly=RBVRenderer"
    x:Class="RBVRenderer.MainPage">
    <ContentPage.Content>
        <StackLayout Padding="20" 
        Spacing="20" BackgroundColor="Blue">

            <me:CircleImage  
                    x:Name="rbi" 
                    WidthRequest="50" 
                    HeightRequest="50"  
                    BorderColor="White"
                    FileSource="cyansquare.png">
            </me:CircleImage>

            <Label Text="Has Border" />
            <Switch BindingContext="{x:Reference rbi}"
                IsToggled="{Binding HasBorder, Mode=OneWayToSource}" />

        </StackLayout>
    </ContentPage.Content>
</ContentPage>