2014-01-16 42 views
8

我正在尝试在Xamarin.iOS应用程序中使用填充创建一个UILabel。在原生Objective-C的应用程序最流行的解决方案是压倒drawTextInRect在Xamarin.iOS中填充UILabel?

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

像这样简单看来,我不能完全弄清楚如何将其翻译为C#。这是我最好的刺吧:

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); 
    } 
} 

这似乎移动标签的文本,但它不调整的标签。

我认为主要问题是我找不到UIEdgeInsetsInsetRect的Xamarin等价物。

有什么建议吗?

回答

16

的C#相当于ObjC功能UIEdgeInsetsInsetRect的是UIEdgeInsets命名InsetRect一个实例方法,它不等同于您的RectangleF计算(这是可能你的问题)。

要使用它,你可以这样做:

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

谢谢!这似乎是Objective-C版本的正确翻译。它按预期转移文本,但文本被剪切到右侧。换句话说,'UILabel'不会调整大小以适应插入。不过,这可能是一个单独的问题。 –

+0

该代码只改变图形,所以'UILabel'不知道插入(并且不会改变它的行为)。 – poupou

+0

这是有道理的。在确定标签的宽度时,我应该考虑什么来考虑插入问题?如果可能,我希望它动态调整大小。 –

1

我已经创建了一个包装是从UIView的派生的任何IOS UI元素的通用填充UIView类。

基本上它将所需的UIView嵌套到另一个视图中,并负责所有的填充工作。

用法:

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 

这里是类:

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(); } 
    } 
} 
+0

public override RectangleF Frame,此方法无法解析 – Signcodeindie

0

,而不是的UILabel子类覆盖DrawText的(),重写它的内在内容的大小。这种方式自动布局考虑填充。例如,以下是我的派生类的UILabel的:

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

正确的方式做到这一点似乎已经略有改变,因为原来的答案给出,我花了一段时间来找出新的正确的语法。在这里,任何人都会遇到这个问题。

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

您必须覆盖bothDrawTextTextRectForBounds。 如果您不覆盖TextRectForBounds,文本将被裁剪。 实际上,您会覆盖此方法来补偿由填充占用的空间,并要求iOS在更大的矩形中绘制文本。

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)); 
    } 
}