UILabel with add-on in Xamarin.iOS?

I am trying to create a UILabel with padding in an Xamarin.iOS application. The most popular solution in native Objective-C applications is to override drawTextInRect :

 - (void)drawTextInRect:(CGRect)rect { UIEdgeInsets insets = {0, 5, 0, 5}; return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)]; } 

Easier, as it seems, I can’t figure out how to translate it to C #. Here is my best hit on it:

 internal class PaddedLabel : UILabel { public UIEdgeInsets Insets { get; set; } public override void DrawText(RectangleF rect) { var padded = new RectangleF(rect.X + Insets.Left, rect.Y, rext.Width + Insets.Left + Insets.Right, rect.Height); base.DrawText(padded); } } 

This seems to move the label text, but it does not resize the label.

I think the main problem is that I cannot find the Xamarin equivalent of UIEdgeInsetsInsetRect .

Any suggestions?

+8
c # ios iphone uilabel
source share
5 answers

The C # equivalent of the ObjC function UIEdgeInsetsInsetRect is a UIEdgeInsets instance method named InsetRect and it is not identical to your RectangleF calculations (which is most likely your problem).

To use it, you can:

 public override void DrawText(RectangleF rect) { base.DrawText (Insets.InsetRect (rect)); } 
+16
source share

I created a generic UDEiew Padding class that wraps any IOS UI element that is derived from UIView.

Basically this is the socket of the desired UIView in a different view and takes care of all the shims.

using:

 var myPaddedView = new PaddedUIView<UILabel>(); myPaddedView.Frame = TheActualFrame; myPaddedView.Padding = 15f myPaddedView.NestedView.Text = "Hello padded world"; // all the label Properties are available without side effects 

Here is the class:

 public class PaddedUIView<T>: UIView where T : UIView, new() { private float _padding; private T _nestedView; public PaddedUIView() { Initialize(); } public PaddedUIView(RectangleF bounds) : base(bounds) { Initialize(); } void Initialize() { if(_nestedView == null) { _nestedView = new T(); this.AddSubview(_nestedView); } _nestedView.Frame = new RectangleF(_padding,_padding,Frame.Width - 2 * _padding, Frame.Height - 2 * _padding); } public T NestedView { get { return _nestedView; } } public float Padding { get { return _padding; } set { if(value != _padding) { _padding = value; Initialize(); }} } public override RectangleF Frame { get { return base.Frame; } set { base.Frame = value; Initialize(); } } } 
+1
source share

Instead of overriding DrawText () in a subclass of UILabel, overriding its own content size. Thus, the automatic layout allows for laying. For example, here is my derived UILabel class:

 public class PaddedLabel : UILabel { private readonly float _top; private readonly float _left; private readonly float _right; private readonly float _bottom; public PaddedLabel(float top, float left, float right, float bottom) { _top = top; _left = left; _right = right; _bottom = bottom; } public override CGSize IntrinsicContentSize => new CGSize( base.IntrinsicContentSize.Width + _left + _right, base.IntrinsicContentSize.Height + _top + _bottom ); } 
0
source share

The right way to do this seems to have changed a bit since the original answer, and it took me a while to figure out the new correct syntax. Here it is for everyone who stumbles about it. This code places Supplement 5 on the left and right sides of the view. This is in Xamarin.iOS

 public override void DrawText(CGRect rect) { rect.X = 5; rect.Width = rect.Width - 10; // or whatever padding settings you want base.DrawText(AlignmentRectInsets.InsetRect(rect)); } 
0
source share

You need to override both DrawText and TextRectForBounds . If you do not override TextRectForBounds , the text will be truncated. In fact, you override this method to compensate for the space that is occupied by the fill and ask iOS to draw the text in a larger rectangle.

 public partial class LabelWithBorder : UILabel { private UIEdgeInsets EdgeInsets = new UIEdgeInsets(5, 5, 5, 5); private UIEdgeInsets InverseEdgeInsets = new UIEdgeInsets(-5, -5, -5, -5); public LabelWithBorder(IntPtr handle) : base(handle) { } public override CoreGraphics.CGRect TextRectForBounds(CoreGraphics.CGRect bounds, nint numberOfLines) { var textRect = base.TextRectForBounds(EdgeInsets.InsetRect(bounds), numberOfLines); return InverseEdgeInsets.InsetRect(textRect); } public override void DrawText(CoreGraphics.CGRect rect) { base.DrawText(EdgeInsets.InsetRect(rect)); } } 
0
source share

All Articles