Make Label display HTML from a string (#4527)
* Use UpdateText * Added missing helper method and UI test * Added missing helper for UWP * Added csproj entry for helper * Resolved rebase conflicts * Update LabelRenderer.cs * Update LabelRenderer.cs * Update LabelRenderer.cs * iOS Merge error fix * Feedback * - uwp fixes * - android fix empty text * - ios fix null and setting text when texttype starts as html * - set _perfectSizeValid = false; after changed AttributedText Setting the AttributedText causes GetDesiredSize to get called which sets _perfectSizeValid to true but at this point this frame still hasn't adjusted to any size change from *LayoutSubViews*. This resets _perfectSizeValid so after the AttributedText set the desiredsize can get pulled again * Renamed PlainText to Text * Fixed initial no HTML styling
This commit is contained in:
Родитель
c0a681e852
Коммит
938a840e68
|
@ -0,0 +1,88 @@
|
|||
using System;
|
||||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
using Xamarin.UITest;
|
||||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
#if UITEST
|
||||
[Category(UITestCategories.Label)]
|
||||
#endif
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.None, 0, "Implementation of Label TextType", PlatformAffected.All)]
|
||||
public class LabelTextType : TestContentPage
|
||||
{
|
||||
protected override void Init()
|
||||
{
|
||||
var label = new Label
|
||||
{
|
||||
AutomationId = "TextTypeLabel",
|
||||
Text = "<h1>Hello World!</h1>"
|
||||
};
|
||||
|
||||
var button = new Button
|
||||
{
|
||||
AutomationId = "ToggleTextTypeButton",
|
||||
Text = "Toggle HTML/Plain"
|
||||
};
|
||||
|
||||
button.Clicked += (s, a) =>
|
||||
{
|
||||
label.TextType = label.TextType == TextType.Html ? TextType.Text : TextType.Html;
|
||||
};
|
||||
|
||||
|
||||
Label htmlLabel = new Label() { TextType = TextType.Html };
|
||||
Label normalLabel = new Label();
|
||||
Label nullLabel = new Label() { TextType = TextType.Html };
|
||||
|
||||
Button toggle = new Button()
|
||||
{
|
||||
Text = "Toggle some more things",
|
||||
Command = new Command(() =>
|
||||
{
|
||||
htmlLabel.Text = $"<b>{DateTime.UtcNow}</b>";
|
||||
normalLabel.Text = $"<b>{DateTime.UtcNow}</b>";
|
||||
|
||||
if (String.IsNullOrWhiteSpace(nullLabel.Text))
|
||||
nullLabel.Text = "hi there";
|
||||
else
|
||||
nullLabel.Text = null;
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
var stacklayout = new StackLayout();
|
||||
stacklayout.Children.Add(label);
|
||||
stacklayout.Children.Add(button);
|
||||
stacklayout.Children.Add(htmlLabel);
|
||||
stacklayout.Children.Add(normalLabel);
|
||||
stacklayout.Children.Add(nullLabel);
|
||||
stacklayout.Children.Add(toggle);
|
||||
|
||||
Content = stacklayout;
|
||||
}
|
||||
|
||||
#if UITEST
|
||||
[Test]
|
||||
public void LabelToggleHtmlAndPlainTextTest()
|
||||
{
|
||||
RunningApp.WaitForElement ("TextTypeLabel");
|
||||
RunningApp.Screenshot ("I see plain text");
|
||||
|
||||
Assert.IsTrue(RunningApp.Query("TextTypeLabel").FirstOrDefault()?.Text == "<h1>Hello World!</h1>");
|
||||
|
||||
RunningApp.Tap("ToggleTextTypeButton");
|
||||
RunningApp.Screenshot ("I see HTML text");
|
||||
|
||||
Assert.IsFalse(RunningApp.Query("TextTypeLabel").FirstOrDefault()?.Text.Contains("<h1>") ?? true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1029,6 +1029,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)Issue6738.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)GitHub6926.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue5503.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)LabelTextType.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">
|
||||
|
|
|
@ -237,6 +237,40 @@ namespace Xamarin.Forms.Controls
|
|||
}
|
||||
);
|
||||
|
||||
var htmlLabelContainer = new ViewContainer<Label>(Test.Label.TextType,
|
||||
new Label
|
||||
{
|
||||
Text = "<h1>Hello world!</h1>",
|
||||
TextType = TextType.Html
|
||||
});
|
||||
|
||||
var htmlLabelMultipleLinesContainer = new ViewContainer<Label>(Test.Label.TextType,
|
||||
new Label
|
||||
{
|
||||
Text = "<h1>Hello world!</h1><p>Lorem <strong>ipsum</strong> bla di bla <i>blabla</i> blablabl ablabla & blablablablabl ablabl ablablabl ablablabla blablablablablablab lablablabla blablab lablablabla blablabl ablablablab lablabla blab lablablabla blablab lablabla blablablablab lablabla blablab lablablabl ablablabla blablablablablabla blablabla</p>",
|
||||
TextType = TextType.Html,
|
||||
MaxLines = 3
|
||||
});
|
||||
|
||||
var toggleLabel = new Label
|
||||
{
|
||||
TextType = TextType.Html,
|
||||
Text = "<h1 style=\"color: red;\">Hello world!</h1><p>Lorem <strong>ipsum</strong></p>"
|
||||
|
||||
};
|
||||
|
||||
var gestureRecognizer = new TapGestureRecognizer();
|
||||
|
||||
gestureRecognizer.Tapped += (s, a) =>
|
||||
{
|
||||
toggleLabel.TextType = toggleLabel.TextType == TextType.Html ? TextType.Text : TextType.Html;
|
||||
};
|
||||
|
||||
toggleLabel.GestureRecognizers.Add(gestureRecognizer);
|
||||
|
||||
var toggleHtmlPlainTextLabelContainer = new ViewContainer<Label>(Test.Label.TextType,
|
||||
toggleLabel);
|
||||
|
||||
Add (namedSizeMediumBoldContainer);
|
||||
Add (namedSizeMediumItalicContainer);
|
||||
Add (namedSizeMediumUnderlineContainer);
|
||||
|
@ -272,6 +306,9 @@ namespace Xamarin.Forms.Controls
|
|||
Add (maxlinesTailTruncContainer);
|
||||
Add (maxlinesWordWrapContainer);
|
||||
Add(paddingContainer);
|
||||
Add (htmlLabelContainer);
|
||||
Add (htmlLabelMultipleLinesContainer);
|
||||
Add (toggleHtmlPlainTextLabelContainer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -90,6 +90,9 @@ namespace Xamarin.Forms
|
|||
|
||||
public static readonly BindableProperty PaddingProperty = PaddingElement.PaddingProperty;
|
||||
|
||||
public static readonly BindableProperty TextTypeProperty = BindableProperty.Create(nameof(TextType), typeof(TextType), typeof(Label), TextType.Text,
|
||||
propertyChanged: (bindable, oldvalue, newvalue) => ((Label)bindable).InvalidateMeasureInternal(InvalidationTrigger.MeasureChanged));
|
||||
|
||||
readonly Lazy<PlatformConfigurationRegistry<Label>> _platformConfigurationRegistry;
|
||||
|
||||
public Label()
|
||||
|
@ -213,6 +216,12 @@ namespace Xamarin.Forms
|
|||
set { SetValue(PaddingProperty, value); }
|
||||
}
|
||||
|
||||
public TextType TextType
|
||||
{
|
||||
get => (TextType)GetValue(TextTypeProperty);
|
||||
set => SetValue(TextTypeProperty, value);
|
||||
}
|
||||
|
||||
double IFontElement.FontSizeDefaultValueCreator() =>
|
||||
Device.GetNamedSize(NamedSize.Default, (Label)this);
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
namespace Xamarin.Forms
|
||||
{
|
||||
public enum TextType
|
||||
{
|
||||
Text,
|
||||
Html
|
||||
}
|
||||
}
|
|
@ -635,7 +635,8 @@ namespace Xamarin.Forms.CustomAttributes
|
|||
VerticalTextAlignmentStart,
|
||||
VerticalTextAlignmentCenter,
|
||||
VerticalTextAlignmentEnd,
|
||||
MaxLines
|
||||
MaxLines,
|
||||
TextType
|
||||
}
|
||||
|
||||
public enum MasterDetailPage
|
||||
|
|
|
@ -251,6 +251,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
|
|||
UpdateGravity();
|
||||
if (e.OldElement?.MaxLines != e.NewElement.MaxLines)
|
||||
UpdateMaxLines();
|
||||
|
||||
UpdatePadding();
|
||||
|
||||
ElevationHelper.SetElevation(this, e.NewElement);
|
||||
|
@ -263,7 +264,8 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
|
|||
|
||||
if (e.PropertyName == Label.HorizontalTextAlignmentProperty.PropertyName || e.PropertyName == Label.VerticalTextAlignmentProperty.PropertyName)
|
||||
UpdateGravity();
|
||||
else if (e.PropertyName == Label.TextColorProperty.PropertyName)
|
||||
else if (e.PropertyName == Label.TextColorProperty.PropertyName ||
|
||||
e.PropertyName == Label.TextTypeProperty.PropertyName)
|
||||
UpdateText();
|
||||
else if (e.PropertyName == Label.FontProperty.PropertyName)
|
||||
UpdateText();
|
||||
|
@ -380,7 +382,23 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
|
|||
SetTextColor(_labelTextColorDefault);
|
||||
_lastUpdateColor = Color.Default;
|
||||
}
|
||||
|
||||
switch (Element.TextType)
|
||||
{
|
||||
case TextType.Html:
|
||||
if (Forms.IsNougatOrNewer)
|
||||
Control.SetText(Html.FromHtml(Element.Text ?? string.Empty, FromHtmlOptions.ModeCompact), BufferType.Spannable);
|
||||
else
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
Control.SetText(Html.FromHtml(Element.Text ?? string.Empty), BufferType.Spannable);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
break;
|
||||
|
||||
default:
|
||||
Text = Element.Text;
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateColor();
|
||||
UpdateFont();
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace Xamarin.Forms
|
|||
static BuildVersionCodes? s_sdkInt;
|
||||
static bool? s_isLollipopOrNewer;
|
||||
static bool? s_isMarshmallowOrNewer;
|
||||
static bool? s_isNougatOrNewer;
|
||||
|
||||
[Obsolete("Context is obsolete as of version 2.5. Please use a local context instead.")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
|
@ -98,6 +99,16 @@ namespace Xamarin.Forms
|
|||
}
|
||||
}
|
||||
|
||||
internal static bool IsNougatOrNewer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!s_isNougatOrNewer.HasValue)
|
||||
s_isNougatOrNewer = (int)Build.VERSION.SdkInt >= 24;
|
||||
return s_isNougatOrNewer.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public static float GetFontSizeNormal(Context context)
|
||||
{
|
||||
float size = 50;
|
||||
|
|
|
@ -135,7 +135,6 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateMaxLines();
|
||||
if (e.OldElement.CharacterSpacing != e.NewElement.CharacterSpacing)
|
||||
UpdateCharacterSpacing();
|
||||
|
||||
}
|
||||
UpdateTextDecorations();
|
||||
UpdatePadding();
|
||||
|
@ -158,13 +157,13 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateLineBreakMode();
|
||||
else if (e.PropertyName == Label.TextDecorationsProperty.PropertyName)
|
||||
UpdateTextDecorations();
|
||||
else if (e.PropertyName == Label.TextProperty.PropertyName || e.PropertyName == Label.FormattedTextProperty.PropertyName)
|
||||
else if (e.IsOneOf(Label.TextProperty, Label.FormattedTextProperty, Label.TextTypeProperty))
|
||||
UpdateText();
|
||||
else if (e.PropertyName == Label.LineHeightProperty.PropertyName)
|
||||
UpdateLineHeight();
|
||||
else if (e.PropertyName == Label.MaxLinesProperty.PropertyName)
|
||||
UpdateMaxLines();
|
||||
else if (e.PropertyName == ImageButton.PaddingProperty.PropertyName)
|
||||
else if (e.PropertyName == Label.PaddingProperty.PropertyName)
|
||||
UpdatePadding();
|
||||
}
|
||||
|
||||
|
@ -242,7 +241,6 @@ namespace Xamarin.Forms.Platform.Android
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void UpdateLineHeight()
|
||||
{
|
||||
_lastSizeRequest = null;
|
||||
|
@ -274,7 +272,25 @@ namespace Xamarin.Forms.Platform.Android
|
|||
_view.SetTextColor(_labelTextColorDefault);
|
||||
_lastUpdateColor = Color.Default;
|
||||
}
|
||||
|
||||
switch (Element.TextType)
|
||||
{
|
||||
|
||||
case TextType.Html:
|
||||
if (Forms.IsNougatOrNewer)
|
||||
Control.SetText(Html.FromHtml(Element.Text ?? string.Empty, FromHtmlOptions.ModeCompact), TextView.BufferType.Spannable);
|
||||
else
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
Control.SetText(Html.FromHtml(Element.Text ?? string.Empty), TextView.BufferType.Spannable);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
break;
|
||||
|
||||
default:
|
||||
_view.Text = Element.Text;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateColor();
|
||||
UpdateFont();
|
||||
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
using System.Xml.Linq;
|
||||
using Windows.UI.Xaml.Documents;
|
||||
|
||||
namespace Xamarin.Forms.Platform.UAP
|
||||
{
|
||||
internal static class LabelHtmlHelper
|
||||
{
|
||||
// All the supported HTML tags
|
||||
internal const string ElementB = "B";
|
||||
internal const string ElementBr = "BR";
|
||||
internal const string ElementEm = "EM";
|
||||
internal const string ElementI = "I";
|
||||
internal const string ElementP = "P";
|
||||
internal const string ElementStrong = "STRONG";
|
||||
internal const string ElementU = "U";
|
||||
internal const string ElementUl = "UL";
|
||||
internal const string ElementLi = "LI";
|
||||
internal const string ElementDiv = "DIV";
|
||||
|
||||
public static void ParseText(XElement element, InlineCollection inlines, Label label)
|
||||
{
|
||||
if (element == null)
|
||||
return;
|
||||
|
||||
var currentInlines = inlines;
|
||||
var elementName = element.Name.ToString().ToUpper();
|
||||
switch (elementName)
|
||||
{
|
||||
case ElementB:
|
||||
case ElementStrong:
|
||||
var bold = new Bold();
|
||||
inlines.Add(bold);
|
||||
currentInlines = bold.Inlines;
|
||||
break;
|
||||
case ElementI:
|
||||
case ElementEm:
|
||||
var italic = new Italic();
|
||||
inlines.Add(italic);
|
||||
currentInlines = italic.Inlines;
|
||||
break;
|
||||
case ElementU:
|
||||
var underline = new Underline();
|
||||
inlines.Add(underline);
|
||||
currentInlines = underline.Inlines;
|
||||
break;
|
||||
case ElementBr:
|
||||
inlines.Add(new LineBreak());
|
||||
break;
|
||||
case ElementP:
|
||||
// Add two line breaks, one for the current text and the second for the gap.
|
||||
if (AddLineBreakIfNeeded(inlines))
|
||||
{
|
||||
inlines.Add(new LineBreak());
|
||||
}
|
||||
|
||||
var paragraphSpan = new Windows.UI.Xaml.Documents.Span();
|
||||
inlines.Add(paragraphSpan);
|
||||
currentInlines = paragraphSpan.Inlines;
|
||||
break;
|
||||
case ElementLi:
|
||||
inlines.Add(new LineBreak());
|
||||
inlines.Add(new Run { Text = " • " });
|
||||
break;
|
||||
case ElementUl:
|
||||
case ElementDiv:
|
||||
AddLineBreakIfNeeded(inlines);
|
||||
var divSpan = new Windows.UI.Xaml.Documents.Span();
|
||||
inlines.Add(divSpan);
|
||||
currentInlines = divSpan.Inlines;
|
||||
break;
|
||||
}
|
||||
foreach (var node in element.Nodes())
|
||||
{
|
||||
if (node is XText textElement)
|
||||
{
|
||||
currentInlines.Add(new Run { Text = textElement.Value });
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseText(node as XElement, currentInlines, label);
|
||||
}
|
||||
}
|
||||
// Add newlines for paragraph tags
|
||||
if (elementName == "ElementP")
|
||||
{
|
||||
currentInlines.Add(new LineBreak());
|
||||
}
|
||||
}
|
||||
|
||||
static bool AddLineBreakIfNeeded(InlineCollection inlines)
|
||||
{
|
||||
if (inlines.Count <= 0)
|
||||
return false;
|
||||
|
||||
var lastInline = inlines[inlines.Count - 1];
|
||||
while ((lastInline is Windows.UI.Xaml.Documents.Span))
|
||||
{
|
||||
var span = (Windows.UI.Xaml.Documents.Span)lastInline;
|
||||
if (span.Inlines.Count > 0)
|
||||
{
|
||||
lastInline = span.Inlines[span.Inlines.Count - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (lastInline is LineBreak)
|
||||
return false;
|
||||
|
||||
inlines.Add(new LineBreak());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml.Linq;
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Text;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Automation.Peers;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Documents;
|
||||
using Xamarin.Forms.Platform.UAP;
|
||||
using Xamarin.Forms.PlatformConfiguration.WindowsSpecific;
|
||||
using Specifics = Xamarin.Forms.PlatformConfiguration.WindowsSpecific.Label;
|
||||
using WThickness = Windows.UI.Xaml.Thickness;
|
||||
|
@ -155,11 +158,8 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == Label.TextProperty.PropertyName ||
|
||||
e.PropertyName == Label.FormattedTextProperty.PropertyName)
|
||||
{
|
||||
if (e.IsOneOf(Label.TextProperty, Label.FormattedTextProperty, Label.TextTypeProperty))
|
||||
UpdateText(Control);
|
||||
}
|
||||
else if (e.PropertyName == Label.TextColorProperty.PropertyName)
|
||||
UpdateColor(Control);
|
||||
else if (e.PropertyName == Label.HorizontalTextAlignmentProperty.PropertyName || e.PropertyName == Label.VerticalTextAlignmentProperty.PropertyName)
|
||||
|
@ -182,6 +182,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
UpdateMaxLines(Control);
|
||||
else if (e.PropertyName == Label.PaddingProperty.PropertyName)
|
||||
UpdatePadding(Control);
|
||||
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
}
|
||||
|
||||
|
@ -327,10 +328,22 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
_perfectSizeValid = false;
|
||||
|
||||
if (textBlock == null)
|
||||
{
|
||||
return;
|
||||
|
||||
switch (Element.TextType)
|
||||
{
|
||||
case TextType.Html:
|
||||
UpdateTextHtml(textBlock);
|
||||
break;
|
||||
|
||||
default:
|
||||
UpdateTextPlainText(textBlock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateTextPlainText(TextBlock textBlock)
|
||||
{
|
||||
Label label = Element;
|
||||
if (label != null)
|
||||
{
|
||||
|
@ -360,6 +373,27 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
}
|
||||
}
|
||||
|
||||
void UpdateTextHtml(TextBlock textBlock)
|
||||
{
|
||||
var text = Element.Text ?? String.Empty;
|
||||
|
||||
// Just in case we are not given text with elements.
|
||||
var modifiedText = string.Format("<div>{0}</div>", text);
|
||||
modifiedText = Regex.Replace(modifiedText, "<br>", "<br></br>", RegexOptions.IgnoreCase);
|
||||
// reset the text because we will add to it.
|
||||
Control.Inlines.Clear();
|
||||
try
|
||||
{
|
||||
var element = XElement.Parse(modifiedText);
|
||||
LabelHtmlHelper.ParseText(element, Control.Inlines, Element);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// if anything goes wrong just show the html
|
||||
textBlock.Text = Windows.Data.Html.HtmlUtilities.ConvertToText(Element.Text);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateDetectReadingOrderFromContent(TextBlock textBlock)
|
||||
{
|
||||
if (Element.IsSet(Specifics.DetectReadingOrderFromContentProperty))
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
<Compile Include="ITitleViewRendererController.cs" />
|
||||
<Compile Include="IToolbarProvider.cs" />
|
||||
<Compile Include="IVisualNativeElementRenderer.cs" />
|
||||
<Compile Include="LabelHtmlHelper.cs" />
|
||||
<Compile Include="NativeBindingExtensions.cs" />
|
||||
<Compile Include="NativeEventWrapper.cs" />
|
||||
<Compile Include="NativePropertyListener.cs" />
|
||||
|
|
|
@ -39,7 +39,8 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
Label.FormattedTextProperty.PropertyName,
|
||||
Label.LineBreakModeProperty.PropertyName,
|
||||
Label.LineHeightProperty.PropertyName,
|
||||
Label.PaddingProperty.PropertyName
|
||||
Label.PaddingProperty.PropertyName,
|
||||
Label.TextTypeProperty.PropertyName
|
||||
};
|
||||
|
||||
public override SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint)
|
||||
|
@ -216,9 +217,10 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
UpdateMaxLines();
|
||||
else if (e.PropertyName == Label.PaddingProperty.PropertyName)
|
||||
UpdatePadding();
|
||||
else if (e.PropertyName == Label.TextTypeProperty.PropertyName)
|
||||
UpdateText();
|
||||
}
|
||||
|
||||
|
||||
protected override NativeLabel CreateNativeControl()
|
||||
{
|
||||
#if __MOBILE__
|
||||
|
@ -236,6 +238,9 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
void UpdateTextDecorations()
|
||||
{
|
||||
if (Element?.TextType != TextType.Text)
|
||||
return;
|
||||
|
||||
if (!Element.IsSet(Label.TextDecorationsProperty))
|
||||
return;
|
||||
|
||||
|
@ -275,6 +280,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
#else
|
||||
Control.AttributedStringValue = newAttributedText;
|
||||
#endif
|
||||
_perfectSizeValid = false;
|
||||
}
|
||||
|
||||
#if __MOBILE__
|
||||
|
@ -372,14 +378,33 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
{
|
||||
#if __MOBILE__
|
||||
|
||||
if (Element?.TextType != TextType.Text)
|
||||
return;
|
||||
|
||||
var textAttr = Control.AttributedText.AddCharacterSpacing(Element.Text, Element.CharacterSpacing);
|
||||
|
||||
if (textAttr != null)
|
||||
Control.AttributedText = textAttr;
|
||||
|
||||
_perfectSizeValid = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void UpdateText()
|
||||
{
|
||||
switch (Element.TextType)
|
||||
{
|
||||
case TextType.Html:
|
||||
UpdateTextHtml();
|
||||
break;
|
||||
|
||||
default:
|
||||
UpdateTextPlainText();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateTextPlainText()
|
||||
{
|
||||
_formatted = Element.FormattedText;
|
||||
if (_formatted == null && Element.LineHeight >= 0)
|
||||
|
@ -407,10 +432,42 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
#else
|
||||
Control.AttributedStringValue = _formatted.ToAttributed(Element, Element.TextColor, Element.HorizontalTextAlignment, Element.LineHeight);
|
||||
#endif
|
||||
_perfectSizeValid = false;
|
||||
}
|
||||
|
||||
void UpdateTextHtml()
|
||||
{
|
||||
string text = Element.Text ?? string.Empty;
|
||||
|
||||
#if __MOBILE__
|
||||
var attr = new NSAttributedStringDocumentAttributes
|
||||
{
|
||||
DocumentType = NSDocumentType.HTML
|
||||
};
|
||||
|
||||
NSError nsError = null;
|
||||
|
||||
Control.AttributedText = new NSAttributedString(text, attr, ref nsError);
|
||||
|
||||
#else
|
||||
var attr = new NSAttributedStringDocumentAttributes
|
||||
{
|
||||
DocumentType = NSDocumentType.HTML
|
||||
};
|
||||
|
||||
var htmlData = new NSMutableData();
|
||||
htmlData.SetData(text);
|
||||
|
||||
Control.AttributedStringValue = new NSAttributedString(htmlData, attr, out _);
|
||||
#endif
|
||||
_perfectSizeValid = false;
|
||||
}
|
||||
|
||||
void UpdateFont()
|
||||
{
|
||||
if (Element?.TextType != TextType.Text)
|
||||
return;
|
||||
|
||||
if (IsTextFormatted)
|
||||
{
|
||||
UpdateFormattedText();
|
||||
|
@ -427,6 +484,9 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
void UpdateTextColor()
|
||||
{
|
||||
if (Element?.TextType != TextType.Text)
|
||||
return;
|
||||
|
||||
if (IsTextFormatted)
|
||||
{
|
||||
UpdateFormattedText();
|
||||
|
|
Загрузка…
Ссылка в новой задаче