Xamarin.University – Upcoming Guest Lecture on Cross-Platform WebRTC

Join me on Tuesday, May 23rd and learn about bringing voice and video conferencing capabilities to your mobile apps! We will talk about the general capabilities of WebRTC, how to bring it to Native mobile development, using it in Xamarin, and extending the capabilities of it.

Leave with an app that lets you share your voice and videos with others!

Bring your devices and your questions!

Here’s a link to the guest lecture! https://university.xamarin.com/guestlectures/cross-platform-webrtc

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Xamarin.Tips – Visual Studio Code Templates/Snippets for MVVM Light

This is a short set of freebies. If you use MVVM Light in your Xamarin or Windows projects, this will save you loads of time. I’ve created a few short cuts for Visual Studio to generate code templates for your ViewModels!

If you aren’t using things like prop or ctor, then you should be! Why write out all that code when you don’t have to!

Take these snippets, and install them into your VS instance. There is documentation here on how to do this: https://msdn.microsoft.com/en-us/library/ms165394.aspx.

For those of you who are not aware of the pain of creating large ViewModel classes, this is what an ordinary property might look like:

private string _myText;
public string MyText
{
    get
    {
        return _myText;
    {
    set
    {
        Set(() => MyText, ref _myText, value);
    }
}

And then setting up a Command:

private ICommand _myCommand;
public ICommand MyCommand
{
    get
    {
        return _myCommand ?? (_myCommand = new RelayCommand(() => { ... }));
    }
}

So let’s look at some templates. I have a repo up here where I’ve added the two we will talk about here, but I’d love to see more in there!

First, the bindable property:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>propb</Title>
			<Shortcut>propb</Shortcut>
			<Description>Code snippet for an automatically implemented bindable property
Language Version: C# 3.0 or higher</Description>
			<Author>Microsoft Corporation</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Declarations>
				<Literal>
					<ID>type</ID>
					<ToolTip>Property type</ToolTip>
					<Default>int</Default>
				</Literal>
				<Literal>
					<ID>property</ID>
					<ToolTip>Property name</ToolTip>
					<Default>MyProperty</Default>
				</Literal>
				<Literal>
					<ID>field</ID>
					<ToolTip>Field name</ToolTip>
					<Default>_myField</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp"><![CDATA[private $type$ $field$;

	public $type$ $property$
	{
		get 
		{ 
			return $field$;
		}
		set 
		{ 
			Set(() => $property$, ref $field$, value);
		}
	}
	$end$]]>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

So now we can type propb > Tab > Tab and get our template going!

And then of course for our RelayCommand:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>rcmd</Title>
			<Shortcut>rcmd</Shortcut>
			<Description>Code snippet for an automatically implemented relay command
Language Version: C# 3.0 or higher</Description>
			<Author>Microsoft Corporation</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Declarations>
				<Literal>
					<ID>property</ID>
					<ToolTip>Property name</ToolTip>
					<Default>MyProperty</Default>
				</Literal>
				<Literal>
					<ID>field</ID>
					<ToolTip>Field name</ToolTip>
					<Default>_myField</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp"><![CDATA[private ICommand $field$;

	public ICommand $property$
	{
		get 
		{ 
			return $field$ ??
				($field$ = new RelayCommand(() => { $end$ }));
		}
	}
	]]>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

The shortcut for this is rcmd > Tab > Tab, and we have our neat little RelayCommand that even brings our cursor back to inside the RelayCommand where we can continue to write out our logic.

Now go out there and write less code faster!

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Xamarin.Tips – Create Your Own Star Wars Intro Text!

Here’s a fun one – let’s make a Xamarin.Forms page that looks like the Star Wars intro scrolling text! I also put the source up here: https://github.com/SuavePirate/StarWarsPage

Here’s the XAML for the page:

StarWarsPage.xaml

<?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:local="clr-namespace:StarWarsPage"              x:Class="StarWarsPage.MainPage">
    <Grid>
        <Image Source="starwarsintrobg.jpg" Aspect="AspectFill" HorizontalOptions="Fill" VerticalOptions="Fill"/>
        <ScrollView x:Name="TextScrollView" Orientation="Vertical" RotationX="24" Padding="16,800">
            <Label x:Name="Text" Text="{StaticResource StarWarsText}" TextColor="Yellow" FontAttributes="Bold" FontSize="30" HorizontalOptions="Fill"/>
        </ScrollView>
    </Grid>
    <ContentPage.Resources>
        <ResourceDictionary>
            <x:String x:Key="StarWarsText">
                It is a period of civil war.
Rebel spaceships, striking
from a hidden base, have won
their first victory against
the evil Galactic Empire.

During the battle, Rebel
spies managed to steal secret
plans to the Empire's
ultimate weapon, the DEATH
STAR, an armored space
station with enough power
to destroy an entire planet.

Pursued by the Empire's
sinister agents, Princess
Leia races home aboard her
starship, custodian of the
stolen plans that can save her
people and restore
freedom to the galaxy....

            </x:String>
        </ResourceDictionary>
    </ContentPage.Resources>
</ContentPage>

The important part here is the RotationX value on the ScrollView. This is going to set the backwards tilt of the scroll. To break down the other parts that make this up – We have a static String resource to use as the text for the intro. In this case I’m using the crawl text from A New Hope. We also wrap the whole thing in a Grid so that we can set up the background Image element.

Now we get a cool view that the user can scroll through at their own reading pace!

StarWars

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Xamarin.Tips – Xamarin.Forms iOS ListView Refresh Spinner Color

Here’s a quick freebie. If you want to change the color of your ListView Refreshing spinner, we can do that with a quick custom renderer!

Here it is as a renderer:

ColoredRefreshListViewRenderer.cs

    ///<summary>
    /// Custom renderer for all list views to use the custom loader color
    /// </summary>

    public class ColoredRefreshListViewRenderer : ListViewRenderer
    {
        ///<summary>
        /// Set the loader color to your custom color
        /// </summary>
        protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
        {
            base.OnElementChanged(e);
            var vc = ((UITableViewController)ViewController);

            // Set the color!
            if (vc?.RefreshControl != null)
                vc.RefreshControl.TintColor = UIColor.FromRGB(135, 200, 21);
        }
    }

Now we get something looking awesome like this:
 

loading_apple_green

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Xamarin.Tips – Changing a TableView’s Separator Color

In previous posts, I talked about the misfortunes of the Xamarin.Forms TableView. In this post, we will look at changing the separator color with a custom renderer.

For some other Xamarin.Tips on upgrading your TableView, check out these two posts on customizing the Section Titles!

Android: Xamarin.Tips – Xamarin.Forms Android Custom TableView Section Titles
iOS: Xamarin.Tips – Xamarin.Forms iOS Custom TableView Section Titles

Let’s get started with a custom view that inherits the TableView and adds a BindableProperty for our SeparatorColor:

ColoredTableView.cs

    public partial class ColoredTableView : TableView
    {
        public static BindableProperty SeparatorColorProperty = BindableProperty.Create("SeparatorColor", typeof(Color), typeof(ColoredTableView), Color.White);
        public Color SeparatorColor
        {
            get
            {
                return (Color)GetValue(SeparatorColorProperty);
            }
            set
            {
                SetValue(SeparatorColorProperty, value);
            }
        }
        public ColoredTableView()
        {
            InitializeComponent();
        }
    }

Now let’s take this view and create our renderers!

Let’s start with Android:

ColoredTableViewRenderer.cs

[assembly: ExportRenderer(typeof(ColoredTableView), typeof(ColoredTableViewRenderer))]
namespace YOUR_ANDROID_NAMESPACE
{
    public class ColoredTableViewRenderer : TableViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
        {
            base.OnElementChanged(e);
            if (Control == null)
                return;

            var listView = Control as Android.Widget.ListView;
            var coloredTableView = (ColoredTableView)Element;
            listView.Divider = new ColorDrawable(coloredTableView.SeparatorColor.ToAndroid());
            listView.DividerHeight = 3;
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if(e.PropertyName == "SeparatorColor")
            {
                var listView = Control as Android.Widget.ListView;
                var coloredTableView = (ColoredTableView)Element;
                listView.Divider = new ColorDrawable(coloredTableView.SeparatorColor.ToAndroid());
            }
        }
    }
}

Basically, we take the color and apply it as a ColorDrawable, including updating when the property changes from our Forms code.

Now let’s write up our iOS renderer:

ColoredTableViewRenderer.cs

[assembly: ExportRenderer(typeof(ColoredTableView), typeof(ColoredTableViewRenderer))]
namespace YOUR_IOS_NAMESPACE
{
    public class ColoredTableViewRenderer : TableViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
        {
            base.OnElementChanged(e);
            if (Control == null)
                return;

            var tableView = Control as UITableView;
            var coloredTableView = Element as ColoredTableView;
            tableView.SeparatorColor = coloredTableView.SeparatorColor.ToUIColor();
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if(e.PropertyName == "SeparatorColor")
            {
                var tableView = Control as UITableView;
                var coloredTableView = Element as ColoredTableView;

                tableView.SeparatorColor = coloredTableView.SeparatorColor.ToUIColor();
            }
        }
    }
}

Similarly to our Android implementation, we set the SeparatorColor of our Native UITableView on set up and when the value changes.

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Xamarin.Tips – Android Shadows on Transparent Views

I talked in a previous post about creating box-shadows on iOS UIViews that are transparent that you can find here: Xamarin.Tips – iOS Shadow on Transparent UIView

This is the Android counterpart! Let’s look at putting some shadows around a view with a fully transparent background. Android presented some completely different challenges compared to iOS. In the iOS solution, we ran into issues with Shadow layers requiring something in front of it to draw the drop shadow. With Android, using a CardView from the design support library gives us access to the Elevation and CardElevation properties which CAN indeed give us shadows around our view even though it is transparent. However, that kills any border on the view. Remember that we are looking for a transparent view, with a solid border, and shadows around it.

The general approach for iOS was to draw two new layers with shadows around the right and bottom sides of the UIView. Using layers allowed us to draw outside the actual frame of the view. However, with iOS, we aren’t so lucky.

So here’s the idea:
1. Adjust the margin and padding to allow us to expand the frame of the view
2. Draw a shadow gradient on the right side
3. Draw a shadow gradient on the bottom side
4. Draw a border around what our inner frame was

Here’s what that looks like in a custom renderer (since the origin of this was a custom Xamarin.Forms view):

TransparentFrameRenderer.cs

[assembly: ExportRenderer(typeof(TransparentFrame), typeof(TransparentFrameRenderer))]
namespace YOUR_ANDROID_NAMESPACE
{
    public class TransparentFrameRenderer : Xamarin.Forms.Platform.Android.AppCompat.FrameRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement != null)
            {
                Element.Margin = new Thickness(-5);
                Element.Padding = new Thickness(15);
                Control.CardElevation = 0;
                Control.PreventCornerOverlap = false;
            }
        }

        protected override void OnDraw(Canvas canvas)
        {
            base.OnDraw(canvas);

            // draw border
            var strokePaint = new Paint();
            strokePaint.SetARGB(255, 255, 255, 255);
            strokePaint.SetStyle(Paint.Style.Stroke);
            strokePaint.StrokeWidth = 2;
            var rect = canvas.ClipBounds;
            var outline = new Rect(15, 15, rect.Right - 15, rect.Bottom - 15);

            var bottomPaint = new Paint();
            bottomPaint.SetStyle(Paint.Style.Fill);
            var shadowShader = new LinearGradient(0, 0, 0, 30, new Android.Graphics.Color(0, 0, 0, 100), new Android.Graphics.Color(0, 0, 0, 0), Shader.TileMode.Mirror);
            bottomPaint.SetShader(shadowShader);

            var rightPaint = new Paint();
            rightPaint.SetStyle(Paint.Style.Fill);
            var rightShader = new LinearGradient(0, 0, 20, 0, new Android.Graphics.Color(0, 0, 0, 100), new Android.Graphics.Color(0, 0, 0, 0), Shader.TileMode.Mirror);
            rightPaint.SetShader(rightShader);

            // draw the bottom and right shadows
            canvas.DrawRect(12, rect.Bottom - 12, rect.Right - 12, rect.Bottom + 3, bottomPaint);
            canvas.DrawRect(rect.Right - 12, 14, rect.Right + 3, rect.Bottom, rightPaint);
            canvas.DrawRect(outline, strokePaint);
        }
    }
}

Look at the Draw override. We are setting up 3 different paints. The first is the Paint for our white border. bottomPaint sets up for our bottom shadow using a LinearGradient as the shader, and similarly, rightPaint sets up our shadow for the right side.

Finally, we call DrawRect for both our shadows, then our border. The values in the DrawRect calls for the shadows are just examples to play with padding and size values. You can play with those as you see fit to make your view look best.

I’ve tested this in some large ListViews to test against the classic Android overdraw issue that can happen, but because it consists of 3 pretty simple strokes, I haven’t run into any performance issues. Hopefully this solution works for you!

This is NOT a complete solution, or a real reusable control, but more of a general approach to rendering shadows around a control with a transparent background.

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Xamarin.Tips – Xamarin.Forms Android Custom TableView Section Titles

Xamarin.Forms’ TableView is a really useful control for displaying static content. However, it has some shortfalls. The one we will look at today is customizing the Section Title.

If you are looking for this solution on iOS, check it out here: Xamarin.Tips – Xamarin.Forms iOS Custom TableView Section Titles

Before reading ahead, I would suggest looking at your solution and assessing whether or not your TableView could be easily replaced by a ListView. I want to point this out, because ListViews have more flexibility for GroupHeader and allow you to put any control in there without having to leave your happy place that is XAML.

If that isn’t the case, keep reading; Let’s look at some simple custom renderers that can solve this problem for Android specifically.

First, let’s create a custom view that inherits TableView:

ColoredTableView.cs

 public partial class ColoredTableView : TableView
    {
        public static BindableProperty GroupHeaderColorProperty = BindableProperty.Create("GroupHeaderColor", typeof(Color), typeof(ColoredTableView), Color.White);
        public Color GroupHeaderColor
        {
            get
            {
                return (Color)GetValue(GroupHeaderColorProperty);
            }
            set
            {
                SetValue(GroupHeaderColorProperty, value);
            }
        }

        public ColoredTableView()
        {
            InitializeComponent();
        }
    }

Now we can create our Android renderer:

ColoredTableViewRenderer

[assembly: ExportRenderer(typeof(ColoredTableView), typeof(ColoredTableViewRenderer))]
namespace YOUR_ANDROID_NAMESPACE
{
    public class ColoredTableViewRenderer : TableViewRenderer
    {
       
        protected override TableViewModelRenderer GetModelRenderer(Android.Widget.ListView listView, TableView view)
        {
            return new CustomHeaderTableViewModelRenderer(Context, listView, view);
        }

        private class CustomHeaderTableViewModelRenderer : TableViewModelRenderer
        {
            private readonly ColoredTableView _coloredTableView;

            public CustomHeaderTableViewModelRenderer(Context context, Android.Widget.ListView listView, TableView view) : base(context, listView, view)
            {
                _coloredTableView = view as ColoredTableView;
            }

            public override Android.Views.View GetView(int position, Android.Views.View convertView, ViewGroup parent)
            {
                var view = base.GetView(position, convertView, parent);

                var element = GetCellForPosition(position);

                // section header will be a TextCell
                if (element.GetType() == typeof(TextCell))
                {
                    try
                    {
                        // Get the textView of the actual layout
                        var textView = ((((view as LinearLayout).GetChildAt(0) as LinearLayout).GetChildAt(1) as LinearLayout).GetChildAt(0) as TextView);

                        // get the divider below the header
                        var divider = (view as LinearLayout).GetChildAt(1);

                        // Set the color
                        textView.SetTextColor(_coloredTableView.GroupHeaderColor.ToAndroid());
                        textView.TextAlignment = Android.Views.TextAlignment.Center;
                        textView.Gravity = GravityFlags.CenterHorizontal;
                        divider.SetBackgroundColor(_coloredTableView.GroupHeaderColor.ToAndroid());
                    }
                    catch (Exception) { }
                }

                return view;
            }
        }
    }
}

Similar to the iOS solution, the important part is our override of GetView. What we are doing here is getting a reference to the inner child native views of our section header (why we check against the type and TextCell). Then we get our actual android TextView and the LinearLayout which is the divider below the header. From there we can change the properties of the views however we prefer. The default behavior of these views are to take the AccentColor from the android styles and use them as the BackgroundColor of the divider and the TextColor of the TextView.

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Xamarin.Tips – Xamarin.Forms iOS Custom TableView Section Titles

Xamarin.Forms’ TableView is a really useful control for displaying static content. However, it has some shortfalls. The one we will look at today is customizing the Section Title. Before reading ahead, I would suggest looking at your solution and assessing whether or not your TableView could be easily replaced by a ListView. I want to point this out, because ListViews have more flexibility for GroupHeader and allow you to put any control in there without having to leave your happy place that is XAML.

If that isn’t the case, keep reading; Let’s look at some simple custom renderers that can solve this problem for iOS specifically (Android to follow).

First, let’s create a custom view that inherits TableView:

ColoredTableView.cs

 public partial class ColoredTableView : TableView
    {
        public static BindableProperty GroupHeaderColorProperty = BindableProperty.Create("GroupHeaderColor", typeof(Color), typeof(ColoredTableView), Color.White);
        public Color GroupHeaderColor
        {
            get
            {
                return (Color)GetValue(GroupHeaderColorProperty);
            }
            set
            {
                SetValue(GroupHeaderColorProperty, value);
            }
        }

        public ColoredTableView()
        {
            InitializeComponent();
        }
    }

Now let’s create a renderer in our iOS project:

ColoredTableViewRenderer.cs


[assembly: ExportRenderer(typeof(ColoredTableView), typeof(ColoredTableViewRenderer))]
namespace YOUR_IOS_NAMESPACE
{
    public class ColoredTableViewRenderer : TableViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
        {
            base.OnElementChanged(e);
            if (Control == null)
                return;

            var tableView = Control as UITableView;
            var coloredTableView = Element as ColoredTableView;
            tableView.WeakDelegate = new CustomHeaderTableModelRenderer(coloredTableView);
        }

        private class CustomHeaderTableModelRenderer : UnEvenTableViewModelRenderer
        {
            private readonly ColoredTableView _coloredTableView;
            public CustomHeaderTableModelRenderer(TableView model) : base(model)
            {
                _coloredTableView = model as ColoredTableView;
            }
            public override UIView GetViewForHeader(UITableView tableView, nint section)
            {
                return new UILabel()
                {
                    Text = TitleForHeader(tableView, section),
                    TextColor = _coloredTableView.GroupHeaderColor.ToUIColor(),
                    TextAlignment = UITextAlignment.Center
                };
            }
        }
    }
}

Basically what we are doing is overriding the WeakDelegate of the native UITableView that is under the Xamarin.Forms TableView. That WeakDelegate is of type TableViewModelRenderer which also inherits the UITableViewSource and holds our native overrides for getting cell heights, etc. Note that this inherits NOT TableViewModelRenderer, but UnEvenTableViewRenderer. This is because my TableView has set HasUnevenRows to true. This is a business rule for my application, but if you aren’t, then you can use the default TableViewModelRenderer.

The important piece is the override of GetViewForHeader. We override this in order to create a custom label that can use the properties and styles we need!

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Xamarin.Controls – BadgeView

Who knew it could be so difficult to just put a number on a circle in Xamarin.Forms? Here’s a freebie to make your life easier in creating your own badges.

Before we dive in, I want to note that with the Xamarin.Forms.Themes, this can be easier. Check out the docs here: https://developer.xamarin.com/guides/xamarin-forms/user-interface/themes/. Basically, they added a StyleClass for BoxView that allows you to render it as a circle (although I’ve had problems with it in the past). This example is going to be avoiding the Themes package with a custom rolled implementation.

To start, we are going to create a custom CircleView. That CircleView is going to inherit from BoxView and use a custom renderer to give us the rounded edges we want. After that, we are going to make a reusable view called BadgeView that will essentially just slap a Label on top of our new CircleView.

Start here, with your CircleView in your PCL or Shared Library:

CircleView.cs

    public partial class CircleView : BoxView
    {
        public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(nameof(CornerRadius), typeof(double), typeof(CircleView), 0.0);

        public double CornerRadius
        {
            get { return (double)GetValue(CornerRadiusProperty); }
            set { SetValue(CornerRadiusProperty, value); }
        }

        public CircleView()
        {
            InitializeComponent();
        }
    }

Now let’s create our custom renderers. I want to note, that for iOS it is much simpler, and could also be done as an Effect rather than a BoxRenderer, however, in order to be consistent with the more complicated Android implementation, we are doing both as renderers.

First, and easiest – iOS:

CircleViewRenderer.cs


[assembly: ExportRenderer(typeof(CircleView), typeof(CircleViewRenderer))]
namespace YourNamespace.iOS
{
    public class CircleViewRenderer : BoxRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
        {
            base.OnElementChanged(e);

            if (Element == null)
                return;

            Layer.MasksToBounds = true;
            Layer.CornerRadius = (float)((CircleView)Element).CornerRadius / 2.0f;
        }

    }
}

and of course Android:

CircleViewRenderer.cs


[assembly: ExportRenderer(typeof(CircleView), typeof(CircleViewRenderer))]
namespace YouNamespace.Droid
{
    public class CircleViewRenderer : BoxRenderer
    {
        private float _cornerRadius;
        private RectF _bounds;
        private Path _path;
        protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
        {
            base.OnElementChanged(e);

            if (Element == null)
            {
                return;
            }
            var element = (CircleView)Element;

            _cornerRadius = TypedValue.ApplyDimension(ComplexUnitType.Dip, (float)element.CornerRadius, Context.Resources.DisplayMetrics);

        }

        protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
        {
            base.OnSizeChanged(w, h, oldw, oldh);
            if (w != oldw && h != oldh)
            {
                _bounds = new RectF(0, 0, w, h);
            }

            _path = new Path();
            _path.Reset();
            _path.AddRoundRect(_bounds, _cornerRadius, _cornerRadius, Path.Direction.Cw);
            _path.Close();
        }

        public override void Draw(Canvas canvas)
        {
            canvas.Save();
            canvas.ClipPath(_path);
            base.Draw(canvas);
            canvas.Restore();
        }
    }
}

Cool. Now we can draw pretty circles in our Xamarin.Forms views:

<views:CircleView CornerRadius="16" WidthRequest="16" HeightRequest="16"/>

Now let’s apply that to a reusable BadgeView.

BadgeView.xaml

<Grid      xmlns="http://xamarin.com/schemas/2014/forms"      xmlns:local="clr-namespace:your_local_namespace"     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"      x:Class="your_local_namespace.BadgeView"     HeightRequest="16"     WidthRequest="16">
    <local:CircleView x:Name="BadgeCircle" HeightRequest="16" WidthRequest="16" CornerRadius="16" VerticalOptions="Center" HorizontalOptions="Center" />
    <Label x:Name="BadgeLabel" TextColor="White" VerticalOptions="Center" HorizontalOptions="Center" VerticalTextAlignment="Center" HorizontalTextAlignment="Center" FontSize="10"/>
</Grid>

BadgeView.xaml.cs

 public partial class BadgeView : Grid
    {
        public static BindableProperty TextProperty = BindableProperty.Create("Text", typeof(string), typeof(BadgeView), "0", propertyChanged: (bindable, oldVal, newVal) =>
        {
            var view = (BadgeView)bindable;
            view.BadgeLabel.Text = (string)newVal;
        });

        public static BindableProperty BadgeColorProperty = BindableProperty.Create("BadgeColor", typeof(Color), typeof(BadgeView), Color.Blue, propertyChanged: (bindable, oldVal, newVal) =>
        {
            var view = (BadgeView)bindable;
            view.BadgeCircle.BackgroundColor = (Color)newVal;
        });

        public string Text
        {
            get
            {
                return (string)GetValue(TextProperty);
            }
            set
            {
                SetValue(TextProperty, value);
            }
        }
        public Color BadgeColor
        {
            get
            {
                return (Color)GetValue(BadgeColorProperty);
            }
            set
            {
                SetValue(BadgeColorProperty, value);
            }
        }
        public BadgeView()
        {
            InitializeComponent();
            BadgeLabel.Text = Text;
            BadgeCircle.BackgroundColor = BadgeColor;
        }
    }

This is obviously a super simple example, but you can always add any other properties you want such as handling changing sizes, corners, shapes, colors, etc.

But now we can see our final results when using our control:

 <Grid>
    <Label HorizontalTextAlignment="Center" Text="Look at me!"/>
    <views:BadgeView Text="3" BadgeColor="Green" VerticalOptions="Start" HorizontalOptions="End"/>
</Grid>

BadgeExample

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Xamarin.Tips – iOS Shadow on Transparent UIView

I ran into another interesting requirement that took some creativity to solve. At a basic level, on iOS, we needed to have a UIView with a fully transparent background that also had a dropshadow (acting more as a box shadow). With its offset being to the bottom right, meaning the shadow should not be visible from the top or left sections of the view.

I know you might be thinking, that sounds like a ridiculous requirement! Why would someone ever do that? It actually gives a pretty cool magnifying look on the large image behind the view, like the UIView was layered above the image and focusing a portion of the large image. I can’t share screenshots, but I would suggest giving the look a try!

But to get to the point, if you haven’t yet, try setting Shadow details on the Layer of a UIView that has a UIColor.Clear background color. You’ll notice that nothing shows up. The next logical thought is to just add another layer that applies the shadow, then add that layer as a sublayer to the view’s main layer. However, that will simply add a gray frame behind yours (since iOS’s shadows act as drop shadows, not box shadows).

At the brink of a mental breakdown, I came up with a solution that worked well for our situation without having to add extra views to act as the shadows or any other wacky workaround (although I will say this workaround is quite wacky).

I did this in Xamarin.Forms, so this is in a Custom renderer for a Frame, but the same thing applies to any UIView. The basic premise is to add two new layers for the bottom portion of the shadow and the right portion.

    public class TransparentFrameRenderer : FrameRenderer
    {

        protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
        {
            base.OnElementChanged(e);
            if(e.NewElement != null)
            {
            }
        }
        public override void Draw(CGRect rect)
        {
            Layer.InsertSublayer(CreateShadowLayer(new CGRect(rect.Width + 2, 3, 4, rect.Height + 2)), 0);
            Layer.InsertSublayer(CreateShadowLayer(new CGRect(3, rect.Height + 2, rect.Width, 4.0f)), 0);
            base.Draw(rect);

        }

        private CALayer CreateShadowLayer(CGRect rect)
        {
            var shadowLayer = new CALayer();
            shadowLayer.BackgroundColor = UIColor.Black.CGColor;
            shadowLayer.ShadowOpacity = 0.8f;
            shadowLayer.ShadowOffset = new CGSize(0, 0);
            shadowLayer.ShadowColor = UIColor.Black.CGColor;
            shadowLayer.ShadowPath = UIBezierPath.FromRect(rect).CGPath;

            return shadowLayer;
        }
    }

Note the helper method to create a layer with the shadow details set to what we need, and inserting two sublayers that set the frame for the layer. These are specific values I used in our situation, but you can easily play with them and also see how the same thing can be applied if your shadow needs to be applied to all four sides (if your light perspective is perfectly perpendicular to the view), inverse of what we have here, or if you need larger or smaller shadows.

This is NOT a complete solution, or a real reusable control, but more of a general approach to rendering shadows around a control with a transparent background.

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!