XF-Material-Library icon indicating copy to clipboard operation
XF-Material-Library copied to clipboard

MaterialTextField can't set text property

Open pedroreglero opened this issue 4 years ago • 9 comments

🐛 Bug Report

You can't set the text value of the MaterialTextField, it crashes the APP. This doesn't happen in the Simulator. Bug happening in iPhone 6S 13.3.1 and with either XF.Material 1.6.0 or 1.5.8

Expected behavior

The text value of the MaterialTextField changes.

Reproduction steps

Created a new blank Xamarin Forms solution. MainPage.xaml

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:ui="clr-namespace:XF.Material.Forms.UI;assembly=XF.Material"
             mc:Ignorable="d"
             x:Class="App1.MainPage">

    <StackLayout>
        <!-- Place new controls here -->
        <ui:MaterialTextField x:Name="txt1"></ui:MaterialTextField>
    </StackLayout>

</ContentPage>

MainPage.xaml.cs

public MainPage()
        {
            InitializeComponent();
            new Thread(new ThreadStart(() =>
            {
                Thread.Sleep(2000);
                txt1.Text = "ofdfk";
            }));
        }

Configuration

Version: 1.x

Platform:

  • [X] :iphone: iOS
  • [ ] :robot: Android
  • [ ] :checkered_flag: WPF
  • [ ] :earth_americas: UWP
  • [ ] :apple: MacOS
  • [ ] :tv: tvOS
  • [X] :monkey: Xamarin.Forms

pedroreglero avatar Mar 06 '20 11:03 pedroreglero

Please any help with this. Makes the plugin unusable in my device.

Thank You.

pedroreglero avatar Mar 09 '20 08:03 pedroreglero

Same issue. Cannot set the text property on iOS.

Deepfreezed avatar Apr 07 '20 16:04 Deepfreezed

We recently started getting this issue, not sure why now all of a sudden, but based on forum search it might be related to a Xamar.iOS update. So with some guidance from other users in the forum I fixed it like this:

`       
private void SetTextFieldValues(List<MaterialSetter> controls)
{
Device.BeginInvokeOnMainThread(() =>
{
controls.ForEach(x =>
{
x.MaterialTextField.Focus();
Thread.Sleep(100);
x.MaterialTextField.SetBinding(MaterialTextField.TextProperty, new Binding($"BindingContext.{x.Value}", source: this));
//x.MaterialTextField.Unfocus();
});

controls.FirstOrDefault().MaterialTextField.Focus();
});
}
class MaterialSetter
{

public MaterialSetter(MaterialTextField materialTextField, string value)
{
MaterialTextField = materialTextField;
Value = value;
}

public MaterialTextField MaterialTextField { get; }
public string Value { get; }
}
`

And this is how I call it:
`            
SetTextFieldValues(new List<MaterialSetter>
{
new MaterialSetter(FullName, "Details.FullNames"),

});
`

mr-rikhamba avatar May 29 '20 18:05 mr-rikhamba

We recently started getting this issue, not sure why now all of a sudden, but based on forum search it might be related to a Xamar.iOS update. So with some guidance from other users in the forum I fixed it like this:

`       
private void SetTextFieldValues(List<MaterialSetter> controls)
{
Device.BeginInvokeOnMainThread(() =>
{
controls.ForEach(x =>
{
x.MaterialTextField.Focus();
Thread.Sleep(100);
x.MaterialTextField.SetBinding(MaterialTextField.TextProperty, new Binding($"BindingContext.{x.Value}", source: this));
//x.MaterialTextField.Unfocus();
});

controls.FirstOrDefault().MaterialTextField.Focus();
});
}
class MaterialSetter
{

public MaterialSetter(MaterialTextField materialTextField, string value)
{
MaterialTextField = materialTextField;
Value = value;
}

public MaterialTextField MaterialTextField { get; }
public string Value { get; }
}
`

And this is how I call it:
`            
SetTextFieldValues(new List<MaterialSetter>
{
new MaterialSetter(FullName, "Details.FullNames"),

});
`

Hi, it doesn't work for me. In the project I had it doesn't crash but it doesn't change the text either. And in a new empty project it crashes.

pedroreglero avatar Aug 14 '20 12:08 pedroreglero

We recently started getting this issue, not sure why now all of a sudden, but based on forum search it might be related to a Xamar.iOS update. So with some guidance from other users in the forum I fixed it like this:

`       
private void SetTextFieldValues(List<MaterialSetter> controls)
{
Device.BeginInvokeOnMainThread(() =>
{
controls.ForEach(x =>
{
x.MaterialTextField.Focus();
Thread.Sleep(100);
x.MaterialTextField.SetBinding(MaterialTextField.TextProperty, new Binding($"BindingContext.{x.Value}", source: this));
//x.MaterialTextField.Unfocus();
});

controls.FirstOrDefault().MaterialTextField.Focus();
});
}
class MaterialSetter
{

public MaterialSetter(MaterialTextField materialTextField, string value)
{
MaterialTextField = materialTextField;
Value = value;
}

public MaterialTextField MaterialTextField { get; }
public string Value { get; }
}
`

And this is how I call it:
`            
SetTextFieldValues(new List<MaterialSetter>
{
new MaterialSetter(FullName, "Details.FullNames"),

});
`

Hi, it doesn't work for me. In the project I had it doesn't crash but it doesn't change the text either. And in a new empty project it crashes.

Ok, so I downgraded to version 1.6.0 and changed:

x.MaterialTextField.SetBinding(MaterialTextField.TextProperty, new Binding($"BindingContext.{x.Value}", source: this));

with:

x.MaterialTextField.Text = x.Value;

and got it working. Than You for the help, very much appreciated

pedroreglero avatar Aug 17 '20 08:08 pedroreglero

Ok, so @mr-rikhamba 's workaround wasn't very stable, so I tried to fix the plugin in stead of hacking a workaround.

The problem was in the file XF-Material-Library-develop\XF.Material\UI\MaterialTextField.xaml.cs in the function AnimateToInactiveOrFocusedStateOnStart .

What I think was happening is that, this plugin uses an animation to move the placeholder to above the Entry. Becouse the page was still not loaded, the animation was making the app crash. I deleted the animation to translate the placeholder and it got fixed. The new function looks like this:

private void AnimateToInactiveOrFocusedStateOnStart(object startObject)
        {
            var placeholderEndY = -(entry.FontSize * 0.8);
            var placeholderEndFont = entry.FontSize * 0.75;

            if (!FloatingPlaceholderEnabled && string.IsNullOrEmpty(entry.Text))
            {
                placeholder.TextColor = PlaceholderColor;
            }

            if (startObject != null && !string.IsNullOrEmpty(Text))
            {
                if (placeholder.TranslationY == placeholderEndY)
                {
                    return;
                }
                entry.Opacity = 0;

                Device.BeginInvokeOnMainThread(() =>
                {

                    if (FloatingPlaceholderEnabled)
                    {
                        placeholder.TranslationY = placeholderEndY;
                        placeholder.TextColor = HasError ? ErrorColor : FloatingPlaceholderColor;
                        entry.Opacity = 1;
                    }

                    if (ShouldAnimateUnderline)
                    {
                        underline.Color = HasError ? ErrorColor : TintColor;
                        underline.HeightRequest = 1;
                        underline.HorizontalOptions = LayoutOptions.FillAndExpand;
                    }
                });

                entry.Opacity = 1;

                return;
            }

            if (startObject != null && string.IsNullOrEmpty(Text) && placeholder.TranslationY == placeholderEndY)
            {
                if (entry.IsFocused)
                {
                    return;
                }

                Device.BeginInvokeOnMainThread(() =>
                {
                    var anim = new Animation();

                    if (FloatingPlaceholderEnabled)
                    {
                        anim.Add(0.0, AnimationDuration, new Animation(v => placeholder.FontSize = v, placeholderEndFont, entry.FontSize, _animationCurve));
                        anim.Add(0.0, AnimationDuration, new Animation(v => placeholder.TranslationY = v, placeholder.TranslationY, 0, _animationCurve, () =>
                        {
                            placeholder.TextColor = PlaceholderColor;
                            entry.Opacity = 1;
                        }));
                    }

                    if (ShouldAnimateUnderline)
                    {
                        anim.Add(0.0, AnimationDuration, new Animation(v => underline.WidthRequest = v, Width, 0, _animationCurve, () => underline.HorizontalOptions = LayoutOptions.Center));
                    }

                    anim.Commit(this, "Anim2", rate: 2, length: (uint)(AnimationDuration * 1000), easing: _animationCurve);
                });
            }
        }

If any of the authors read this, you could modify it for the next release. Thank You.

pedroreglero avatar Aug 19 '20 11:08 pedroreglero

Ok great @pedroreglero , I'm glad you found the route cause for the issue, for now the hack has worked well for us but we are considering stripping it out all together in the future in favour of default XF Entry.

mr-rikhamba avatar Aug 19 '20 11:08 mr-rikhamba

Ok great @pedroreglero , I'm glad you found the route cause for the issue, for now the hack has worked well for us but we are considering stripping it out all together in the future in favour of default XF Entry.

I'm happy we figured this out, this plugin is great, i wanted to fix it before making a custom entry myself.

Thank you for the help.

pedroreglero avatar Aug 19 '20 11:08 pedroreglero

@pedroreglero can you make a PR with the fix?

martijn00 avatar Aug 24 '20 19:08 martijn00