C# 是否在Xamarin.iOS中使用带填充的UILabel?
我正在尝试在我的Xamarin.iOS应用程序中创建一个带有填充的C# 是否在Xamarin.iOS中使用带填充的UILabel?,c#,ios,iphone,xamarin.ios,uilabel,C#,Ios,Iphone,Xamarin.ios,Uilabel,我正在尝试在我的Xamarin.iOS应用程序中创建一个带有填充的UILabel。本机Objective-C应用程序中最流行的解决方案是覆盖drawTextInRect: - (void)drawTextInRect:(CGRect)rect { UIEdgeInsets insets = {0, 5, 0, 5}; return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)]; } 这看起来很简单,但我不太
UILabel
。本机Objective-C应用程序中最流行的解决方案是覆盖drawTextInRect
:
- (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);
}
}
这似乎确实会移动标签的文本,但不会调整标签的大小
我认为主要的问题是,我找不到Xamarin等效的UIEdgeInsetsInsetRect
有什么建议吗?ObjC函数的C#等价物UIEdgeInsetsInsetRect
是名为InsetRect
的UIEdgeInsets
的实例方法,它与您的RectangleF
计算不同(这可能是您的问题)
要使用它,您可以执行以下操作:
public override void DrawText(RectangleF rect)
{
base.DrawText (Insets.InsetRect (rect));
}
我创建了一个通用的Padding UIView类,它封装了从UIView派生的任何IOS UI元素 基本上,它将所需的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
var myPaddedView=new PaddedUIView();
myPaddedView.Frame=实际帧;
myPaddedView.Padding=15f
myPaddedView.NestedView.Text=“你好,填充世界”//所有标签属性都可用,没有副作用
下面是课堂:
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(); }
}
}
public类PaddedUIView:UIView其中T:UIView,new()
{
私人浮动(padding);;
私人T_nestedView;
公共PaddedUIView()
{
初始化();
}
公共填充视图(矩形边界)
:基本(边界)
{
初始化();
}
void Initialize()
{
如果(_nestedView==null)
{
_nestedView=newt();
this.AddSubview(_nestedView);
}
_nestedView.Frame=新矩形F(_padding,_padding,Frame.Width-2*_padding,Frame.Height-2*_padding);
}
公共T嵌套视图
{
获取{return\u nestedView;}
}
公共浮子填充
{
获取{return\u padding;}
设置{if(value!={u padding=value;Initialize();}}
}
公共覆盖矩形框架
{
获取{return base.Frame;}
set{base.Frame=value;Initialize();}
}
}
与其重写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
);
}
自给出最初的答案以来,正确的方法似乎略有改变,我花了一段时间才弄明白新的正确语法。这是给任何偶然发现这一点的人的。此代码将在视图的左侧和右侧放置5的填充。这是在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));
}
您必须覆盖DrawText
和。
如果不重写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));
}
}
谢谢这似乎是Objective-C版本的正确翻译。它会按预期移动文本,但文本会被剪裁到右侧。换句话说,
UILabel
不会调整大小以适应插入。不过,这可能是一个单独的问题。该代码只会更改图形,因此UILabel
不知道插入(并且不会更改其行为)。这是有道理的。在确定标签宽度时,我应该考虑插图的内容,有什么建议吗?如果可能的话,我希望它能动态调整大小。我不确定你想要的是什么样的结果-但是在这方面有很多类似的问题,例如,你可能想研究(并转换为C)。如果没有任何东西符合你的需要,那么再问另一个(更精确的,例如图片)问题寻求帮助。谢谢——我发布了一个屏幕截图:public override RectangleF Frame,这个方法无法解决问题