I have created a custom renderer for a Xamarin.Forms Label in order to give it a border and some padding. The border was no problem, accessing properties on Control.Layer in OnElementChanged, but I found that adding padding between the border and text was not so straightforward.
I found some solutions that involved subclassing UILabel and overriding DrawText and utilizing UIEdgeInsets to adjust the rect in which the text is drawn. This is as far as I got, as now I am at the point where I have subclassed UILabel but am unsure as to how I can use my subclass as the native control backing my custom renderer.
I found reference to using SetNativeControl() in the renderer to specify the native control backing the renderer, but I would like to retain any data binding there may be between the control and TagLabel instance that my common code interacts with and I fear this may break it without knowing how the LabelRenderer class implements these data bindings.
Any insight would by greatly appreciated!
Here's some code:
TagLabel.cs
using Xamarin.Forms;
namespace Valor
{
public class TagLabel : Label
{
}
}
TagLabelRenderer.cs
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using MyProject;
using MyProject.iOS;
using UIKit;
[assembly: ExportRenderer (typeof(TagLabel), typeof(TagLabelRenderer))]
namespace Valor.iOS
{
public class TagUILabel : UILabel {
public UIEdgeInsets EdgeInsets { get; set; } = UIEdgeInsets.Zero;
public override void DrawText (CoreGraphics.CGRect rect)
{
base.DrawText (EdgeInsets.InsetRect (rect));
}
}
public class TagLabelRenderer : LabelRenderer
{
protected override void OnElementChanged (ElementChangedEventArgs<Label> e)
{
base.OnElementChanged (e);
if (Control != null) {
Control.Layer.BackgroundColor = Color.Red.ToCGColor ();
Control.Layer.BorderColor = Color.Blue.ToCGColor ();
Control.Layer.BorderWidth = (nfloat) 1.0;
Control.Layer.CornerRadius = (nfloat) 5.0;
}
}
}
}