如何在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方法进行欺骗。这个答案显示了你可以做些什么来获得所有东西的实际尺寸