代码之家  ›  专栏  ›  技术社区  ›  Christine

如何在xamarin forms ios自定义呈现程序中获取文本并在下面添加另一行?

  •  1
  • Christine  · 技术社区  · 6 年前

    我正在创建一个自定义渲染器,以在图像的半透明空白处显示标题和描述。如果标题比图像宽,则应换行到第二行,如果有空间,则可在下面显示可选说明。在android中,我可以使用staticlayout来实现这一点:

                // 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,将textluncutionmode设置为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);
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Ax1le    6 年前

    为什么不试试自动布局?要在原始图像上添加背景视图和两种类型的文本。 CALayer 可能会达到您的效果,但它不能使用自动布局,因此您需要使用硬代码(计算文本高度和层的位置)来构造它。你也说过

    我不能把课文包装起来。我也不知道该怎么做 倾斜层的实际高度以便我可以定位描述层 在它下面。

    在图像的自定义渲染器中,由于尚未渲染此控件,因此 Frame HeightRequest 也是未知的。然后您将无法获得正确的帧和层,因此文本将不会显示。我想最好的办法就是 自动删除 :

    // 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将根据titleLabel和descLabel扩展其高度。最大高度将是原始图像的高度。此外,titleLabel将根据其内容自动计算其大小。如果房间允许,描述标签也将始终位于标题标签的下方。

    您可以调整这些约束以满足自己的需求。