有没有办法可以在标签内部使用Spans并且还有合理的理由?

时间:2017-10-27 08:30:59

标签: xamarin xamarin.forms

我正在使用此代码为标签内的文字添加一些颜色:

<Label.FormattedText>
  <FormattedString>
     <Span Text="I would like the word " />
     <Span Text="HERE" ForegroundColor="Red" FontAttributes="Bold" />
     <Span Text="to be in a bold font" />
   </FormattedString>
</Label.FormattedText>

以前我一直在使用此渲染代码来证明标签的合理性:

public class JustifiedLabelRenderer : LabelRenderer
{
    public JustifiedLabelRenderer() {}

    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);

        //if we have a new forms element, we want to update text with font style (as specified in forms-pcl) on native control
        if (e.NewElement != null)
            UpdateTextOnControl();
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        //if there is change in text or font-style, trigger update to redraw control
        if (e.PropertyName == nameof(Label.Text)
           || e.PropertyName == nameof(Label.FontFamily)
           || e.PropertyName == nameof(Label.FontSize)
           || e.PropertyName == nameof(Label.TextColor)
           || e.PropertyName == nameof(Label.FontAttributes))
        {
            UpdateTextOnControl();
        }
    }

    void UpdateTextOnControl()
    {
        if (Control == null)
            return;

        //define paragraph-style
        var style = new NSMutableParagraphStyle()
        {
            Alignment = UITextAlignment.Justified,
            FirstLineHeadIndent = 0.001f,
        };

        //define attributes that use both paragraph-style, and font-style 
        var uiAttr = new UIStringAttributes()
        {
            ParagraphStyle = style,
            BaselineOffset = 0,

            Font = Control.Font
        };

        //define frame to ensure justify alignment is applied
        Control.Frame = new System.Drawing.RectangleF(0, 0, (float)Element.Width, (float)Element.Height);

        //set new text with ui-style-attributes to native control (UILabel)
        var stringToJustify = Control.Text ?? string.Empty;
        var attributedString = new Foundation.NSAttributedString(stringToJustify, uiAttr.Dictionary);
        Control.AttributedText = attributedString;
        Control.Lines = 0;
    }

当我尝试使用此代码来获得彩色对齐标签时,对span字体和颜色的更改不再显示。

有没有一种方法可以让我的标签既合理又有颜色跨度呢?

这是我正在使用的标签的XAML定义:

<local:JustifiedLabel x:Name="c0Label" />

这是填充它的代码:

var s = new FormattedString();
s.Spans.Add(new Span { Text = "test words test words test words test words test words test words", ForegroundColor = Color.Red});
s.Spans.Add(new Span { Text = "ABCDEFG", ForegroundColor = Color.Black });
s.Spans.Add(new Span { Text = " test words test words test words test words test words test words test words test words test words test words test words test words ", ForegroundColor = Color.FromHex("555555") });
c0Label.FormattedText = s;

1 个答案:

答案 0 :(得分:3)

您必须更新渲染器以考虑FormattedText。例如:尝试将渲染器逻辑更改为以下:

public class JustifiedLabelRenderer : LabelRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);

        //if we have a new forms element, update text
        if (e.NewElement != null)
            UpdateTextOnControl();
    }

    protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        //if there is change in formatted-text, trigger update to redraw control
        if (e.PropertyName == nameof(Label.FormattedText))
        {
            UpdateTextOnControl();
        }
    }

    void UpdateTextOnControl()
    {
        if (Control == null)
            return;

        //define paragraph-style
        var style = new NSMutableParagraphStyle()
        {
            Alignment = UITextAlignment.Justified,
            FirstLineHeadIndent = 0.001f,

        };

        //define frame to ensure justify alignment is applied
        Control.Frame = new RectangleF(0, 0, (float)Element.Width, (float)Element.Height);
        Control.Lines = 0;

        if (Element.FormattedText.ToAttributed(Element.Font, Element.TextColor) is NSMutableAttributedString attrText)
        {
            var fullRange = new NSRange(0, attrText.Length);
            attrText.AddAttribute(UIStringAttributeKey.ParagraphStyle, style, fullRange);
            Control.AttributedText = attrText;
        }
    }
}