Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Bug] iOS label can't un-set text decorations when updating text at the same time #11954

Closed
Eilon opened this issue Aug 28, 2020 · 7 comments · Fixed by #14907
Closed

[Bug] iOS label can't un-set text decorations when updating text at the same time #11954

Eilon opened this issue Aug 28, 2020 · 7 comments · Fixed by #14907

Comments

@Eilon
Copy link
Contributor

Eilon commented Aug 28, 2020

Description

On iOS specifically, un-setting TextDecoration (such as removing StrikeThrough) is a no-op when the Text is updated at the same time. Android works fine. It's probably not just the Text property but it does repro that way.

Steps to Reproduce

  1. Use iOS Simulator
  2. Have a label with some text
  3. Via a Button (or whatever), change the label's text and SET TextDecoration=TextDecorations.Strikethrough.
  4. Via a Button (or whatever), change the label's text and SET TextDecoration=TextDecorations.None.

If you DON'T change the label's text at the same time, then it works (strikethrough will get set, and then un-set).

Possibly related, but unsure:

Expected Behavior

Label's text should change every time, and the text decorations should change every time

Actual Behavior

Label's text changes but the strikethrough style never un-sets (it always stays as Strikethrough). Same happens with Underline.

Basic Information

  • Version with issue:
     <PackageReference Include="Xamarin.Forms" Version="4.8.0.1269" />
  • Last known good version: Don't know.
  • IDE: VS2019 on Windows
  • Platform Target Frameworks:
    • iOS: Latest?
    • Android: Latest?

Screenshots

image

Repro code

Start with basic XAML app.

Use this XAML in the MainPage:

    <StackLayout>
        <Label FontSize="16" Padding="30,24,30,0" x:Name="NiceLabel" Text="Default text" />
        <Button Clicked="Button_Clicked" Text="Toggle" />
    </StackLayout>

And this C# for MainPage's codebehind:

    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();

            // Initialize label
            UpdateLabel();
        }

        private bool _isStrikethrough;

        private void Button_Clicked(object sender, EventArgs e)
        {
            // Toggle strike-through and update label
            _isStrikethrough = !_isStrikethrough;
            UpdateLabel();
        }

        private void UpdateLabel()
        {
            NiceLabel.TextDecorations = _isStrikethrough ? TextDecorations.Strikethrough : TextDecorations.None;

            // Comment out the next line and it starts working again
            NiceLabel.Text = "Is it strikethrough? " + _isStrikethrough.ToString();
        }
    }

Workaround

Unknown

@Eilon Eilon added t/bug 🐛 s/unverified New report that has yet to be verified labels Aug 28, 2020
@Eilon Eilon changed the title [Bug] iOS label can't un-set strikethrough style when updating text at the same time [Bug] iOS label can't un-set text decorations when updating text at the same time Aug 28, 2020
Eilon added a commit to Eilon/Rezipe that referenced this issue Aug 28, 2020
@hartez hartez removed the s/unverified New report that has yet to be verified label Sep 3, 2020
@samhouts samhouts added this to the 5.0.0 milestone Sep 8, 2020
@feokuma
Copy link

feokuma commented Sep 24, 2020

Maybe I've a related bug. I have a Label using TextDecorations.Underline and when I change the text then a can't remove the underline anymore. But if I doesn't change the text, I can control the TextDecorations normally.

@Cacuci
Copy link

Cacuci commented Sep 25, 2020

I have same problem in Android. I am using Xamarin.Forms" Version="4.8.0.1364".

@samhouts samhouts removed this from the 5.0.0 milestone Nov 2, 2020
@JVHE
Copy link

JVHE commented Dec 10, 2020

I found a dirty bypass solution of this.

  1. Declare two labels in the area where you want to use strikethrough.
  2. Use the existing settings for one label.
  3. For the other label, set strikethrough and any other options you want to set.
  4. And use the IsVisible property to adjust the desired state.

this is a sample code

public class MyLabelLayout : Layout<View>
{
    private readonly Label _label;
    // since TextDecorations.Strikethrough can't remove when is set, so declared one more label which contains Strikethrough property
    private readonly Label _labelWithStrikethrough;

    private bool _isStrikethrough;
    public bool IsStrikethrough
    {
        get => _isStrikethrough;
        set
        {
            if (_isStrikethrough == value) return;
            UpdateLabel(value);
        }
    }

    private void UpdateLabel(bool isStrikethrough)
    {
        _label.IsVisible = !isStrikethrough;
        _labelWithStrikethrough.IsVisible = isStrikethrough;
    }

    public MyLabelLayout(bool isStrikethrough = false)
    {
        _label = new Label
        {
              // label properties...
              TextDecorations = TextDecorations.None
        };
        Children.Add(_label);

        _labelWithStrikethrough = new Label
        {
              // label properties...
              TextDecorations = TextDecorations.Strikethrough
        };
        Children.Add(_labelWithStrikethrough);

        _label.SetBinding(Label.TextProperty, "MyText");
        _labelWithStrikethrough .SetBinding(Label.TextProperty, "MyText");

        IsStrikethrough = isStrikethrough;
        UpdateLabel(isStrikethrough);
    }

    protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
    {
        return _label.Measure(widthConstraint, heightConstraint);
    }

    protected override void LayoutChildren(double x, double y, double width, double height)
    {
        _label.Layout(new Rectangle(x, y, width, height));
        _labelWithStrikethrough .Layout(new Rectangle(x, y, width, height));
    }
}

Of course, you can write better code than this simple code I wrote. Hope you use it well.

The regrettable thing I think while using Xamarin is that many functions that I expect to work naturally do not work properly. So I spend a lot of time implementing such a bypass workaround, and the codebase is getting bigger. Of course, you'll be busy spending a lot of time solving a lot of high-priority tasks, but I think that if there is no guarantee that someday these trivial problems will be solved, I might give up on Xamarin and move on to other frameworks or native development. I am sorry to say this without even contributing to this.

@JohnHDev

This comment has been minimized.

@lucafederli
Copy link

Any updates on this issue?

@danielroth1
Copy link

Workaround: Use Label.FormattedText instead of Label.Text
#8272 (comment)
#8272 (comment)

@jfversluis
Copy link
Member

Hey everyone, I know it's been a while, thanks for your patience.

I have a PR out for this, you can find it at (#14907) if anyone is still willing or able to test this, please follow these instructions. Since the Label is a widely used control I would want to test this very well to make sure this doesn't break anything.

Please let me know, thanks! :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
10 participants