如何在Xamarin Forms iOS自定义渲染器中让文本换行并在下面添加另一行?
我正在创建一个自定义渲染器,以便在图像的半透明空白中显示标题和描述。如果标题比图像宽,则应换行至第二行,如果有空间,则可在下面显示可选说明。在安卓系统中,我可以使用静态布局来实现这一点:如何在Xamarin Forms iOS自定义渲染器中让文本换行并在下面添加另一行?,ios,xamarin.forms,custom-renderer,Ios,Xamarin.forms,Custom Renderer,我正在创建一个自定义渲染器,以便在图像的半透明空白中显示标题和描述。如果标题比图像宽,则应换行至第二行,如果有空间,则可在下面显示可选说明。在安卓系统中,我可以使用静态布局来实现这一点: // Create text rectangle var height = Height / 3; canvas.Save(); canvas.ClipRect(0, Height - height, Width,
// Create text rectangle
var height = Height / 3;
canvas.Save();
canvas.ClipRect(0, Height - height, Width, Height);
canvas.DrawARGB(191, 255, 255, 255);
canvas.Restore();
var item = ((ImageTile) Element).Item;
var textSize = (height - 15) / 2;
var textPaint = new TextPaint
{
StrokeWidth = 5,
TextSize = textSize,
FakeBoldText = true,
};
if (Build.VERSION.SdkInt >= BuildVersionCodes.Honeycomb)
SetLayerType(LayerType.Software, textPaint);
textPaint.SetStyle(Paint.Style.Fill);
textPaint.Color = global::Android.Graphics.Color.Black;
// init StaticLayout for text
var titleLayout = new StaticLayout(
item.Title, textPaint, Width - 10, Android.Text.Layout.Alignment.AlignNormal, 1.0f, 0.0f, false);
canvas.Translate(5, Height - height + 5);
titleLayout.Draw(canvas);
canvas.Restore();
textPaint = new TextPaint
{
StrokeWidth = 4,
TextSize = textSize - 10,
};
if (Build.VERSION.SdkInt >= BuildVersionCodes.Honeycomb)
SetLayerType(LayerType.Software, textPaint);
var descLayout = new StaticLayout(
item.Description, textPaint, Width - 10, Android.Text.Layout.Alignment.AlignNormal, 1.0f, 0.0f, false);
canvas.Translate(5, Height - height + titleLayout.Height + 5);
descLayout.Draw(canvas);
canvas.Restore();
在iOS中,我使用CATextLayers,但即使我定义了框架并将Wrapped设置为true,将TextTruncationMode设置为None,也无法将文本包装。我也不知道如何得到倾斜层的实际高度,这样我就可以在它下面定位描述层。这就是我到目前为止所做的,它将标题和描述相互重叠,没有包装
var textLayer = new CALayer();
var textRec = new CGRect(0, element.HeightRequest - textheight, element.WidthRequest,
textheight);
textLayer.Frame = textRec;
var backgroundcolor = Color.FromRgba(255, 255, 255, .25).ToCGColor();
textLayer.BackgroundColor = backgroundcolor;
Control.Layer.AddSublayer(textLayer);
var titleLayer = new CATextLayer
{
String = element.Item.Title,
ForegroundColor = Color.Black.ToCGColor(),
FontSize = 14,
Wrapped = true,
TextTruncationMode = CATextLayerTruncationMode.None,
TextAlignmentMode = CATextLayerAlignmentMode.Left,
//Bounds = new CGRect(2, element.HeightRequest - textheight + 2, element.WidthRequest - 4,
// textheight - 4),
};
var titleRec = new CGRect(2, element.HeightRequest - textheight + 2, element.WidthRequest - 4,
textheight - 4);
titleLayer.Frame = titleRec;
Control.Layer.AddSublayer(titleLayer);
var descLayer = new CATextLayer
{
String = element.Item.Description,
ForegroundColor = Color.Black.ToCGColor(),
FontSize = 12,
Wrapped = true,
TextTruncationMode = CATextLayerTruncationMode.None,
};
var descRec = new CGRect(2, element.HeightRequest - textheight + 2, element.WidthRequest - 4,
textheight - 4);
descLayer.ContentsRect = descRec;
Control.Layer.AddSublayer(descLayer);
为什么不试试自动布局呢?您希望在原始图像上添加背景视图和两种类型的文本
CALayer
可能会达到您的效果,但它不能使用自动布局,因此您需要使用硬代码(计算文本高度和层的位置)来构建它。你还说
我无法将文本换行。而且我也不知道该怎么做
倾斜层的实际高度,以便我可以定位描述层
在它下面
在图像的自定义渲染器中,由于尚未渲染此控件,因此其帧
和高度请求
也是未知的。然后,您将无法获得正确的帧或层,因此文本将不会显示。我认为最好的方法是使用自动布局:
// Create a view to hold content just like your textLayer
UIView bgView = new UIView();
bgView.BackgroundColor = UIColor.FromRGBA(1, 1, 1, 0.25f);
bgView.TranslatesAutoresizingMaskIntoConstraints = false;
Control.AddSubview(bgView);
bgView.LeadingAnchor.ConstraintEqualTo(Control.LeadingAnchor).Active = true;
bgView.TopAnchor.ConstraintGreaterThanOrEqualTo(Control.TopAnchor).Active = true;
bgView.TrailingAnchor.ConstraintEqualTo(Control.TrailingAnchor).Active = true;
bgView.BottomAnchor.ConstraintEqualTo(Control.BottomAnchor).Active = true;
UILabel titleLabel = new UILabel();
bgView.AddSubview(titleLabel);
titleLabel.TranslatesAutoresizingMaskIntoConstraints = false;
// Set this property to 0, then your label will move to several lines if your text is too large.
titleLabel.Lines = 0;
titleLabel.Font = UIFont.SystemFontOfSize(14);
titleLabel.Text = Element.Item.Title;
titleLabel.LeadingAnchor.ConstraintEqualTo(bgView.LeadingAnchor).Active = true;
titleLabel.TopAnchor.ConstraintEqualTo(bgView.TopAnchor).Active = true;
titleLabel.TrailingAnchor.ConstraintEqualTo(bgView.TrailingAnchor).Active = true;
// This constraint will show the titleLabel's content at high priority. It means show the descLabel if the image has enough place.
titleLabel.SetContentHuggingPriority(249, UILayoutConstraintAxis.Vertical);
UILabel descLabel = new UILabel();
bgView.AddSubview(descLabel);
descLabel.TranslatesAutoresizingMaskIntoConstraints = false;
descLabel.Lines = 0;
descLabel.Text = Element.Item.Description;
descLabel.Font = UIFont.SystemFontOfSize(12);
descLabel.LeadingAnchor.ConstraintEqualTo(bgView.LeadingAnchor).Active = true;
descLabel.TopAnchor.ConstraintEqualTo(titleLabel.BottomAnchor).Active = true;
descLabel.TrailingAnchor.ConstraintEqualTo(bgView.TrailingAnchor).Active = true;
descLabel.BottomAnchor.ConstraintEqualTo(bgView.BottomAnchor).Active = true;
这样,bgView将根据标题标签和descLabel扩展其高度。最大高度将是原始图像的高度。此外,titleLabel将根据其内容自动计算其大小。此外,如果房间允许,描述标签将始终位于标题标签下方
您可以调整这些约束以满足您自己的需求。您可以通过使用UILabel和其上的SizeThatFits方法进行欺骗。这个答案显示了你可以做些什么来获得所有东西的实际尺寸