0
votes

Hi Guys, I'm building an app that has an Entry similar to that of tinder, does anyone have an idea on how I can achieve this. I tried creating multiple entries and move focus on the text entered but deleting is the issue as TextChaned method is only called when there is text

1
Hi , you can custom Entry Renderer to implement it in Native iOS.Junior Jiang
No, TextChanged actually also called when there is no text, you can notice that there is OldValue and NewValue when text change. Perhaps you can show your code in text change part.Lee

1 Answers

1
votes

In Xamarin.Forms , you can Custom a Entry Render View in iOS to implement it .

Create a custom Entry :

public class CustomEntry : Entry
{

}

Then in Native iOS, create a CustomEntryRenderer

public class CustomEntryRenderer : EntryRenderer
{
    private UITextField textField;
    int numberCount = 6;
    nfloat itemMargin =20;
    List<UILabel> labels = new List<UILabel>();
    List<UIView> lines = new List<UIView>();
    UIControl maskView = new UIControl();

    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);
        textField = (UITextField)this.Control;
        //textField.ReturnKeyType = UIReturnKeyType.Done;
        textField.KeyboardType = UIKeyboardType.NumberPad;
        textField.AutocapitalizationType = UITextAutocapitalizationType.None;
        textField.TextColor = UIColor.Clear;
        textField.TintColor = UIColor.Clear;
        textField.EditingChanged += TextField_EditingChanged;

        UIButton maskView = new UIButton();
        maskView.BackgroundColor = UIColor.White;
        maskView.TouchUpInside += MaskView_TouchUpInside;
        textField.AddSubview(maskView);
        this.maskView = maskView;

        for (int i = 0; i < numberCount; i++)
        {
            UILabel label = new UILabel();
            label.TextAlignment = UITextAlignment.Center;
            label.TextColor = UIColor.DarkTextColor;
            label.Font = UIFont.FromName("PingFangSC-Regular", 41);
            textField.AddSubview(label);
            labels.Add(label);
        }

        for(int i = 0; i < numberCount; i++)
        {
            UIView line = new UIView();
            line.BackgroundColor = UIColor.Purple;
            textField.AddSubview(line);
            lines.Add(line);
        }

    }

    public override void LayoutSubviews()
    {
        base.LayoutSubviews();
        nfloat temp = textField.Bounds.Size.Width - (itemMargin * (numberCount - 1));
        nfloat w = temp / numberCount;
        nfloat x = 0;

        for(int i = 0; i < labels.Count; i++)
        {
            x = i * (w + itemMargin);
            UILabel label = labels[i];
            label.Frame = new CGRect(x, 0, w, textField.Bounds.Size.Height);

            UIView line = lines[i];
            line.Frame = new CGRect(x, textField.Bounds.Size.Height - 1, w, 1);
        }
        maskView.Frame = textField.Bounds;

    }

    private void MaskView_TouchUpInside(object sender, EventArgs e)
    {
        textField.BecomeFirstResponder();
    }

    private void TextField_EditingChanged(object sender, EventArgs e)
    {
        if(textField.Text.Length > numberCount)
        {
            //Range range = new Range(0, numberCount);

            textField.Text = textField.Text.Substring(0, numberCount);
        }

        for(int i = 0; i < numberCount; i++)
        {
            UILabel label = labels[i];
            if(i< textField.Text.Length)
            {
                label.Text = textField.Text.Substring(i, 1);
            }
            else
            {
                label.Text = "";
            }
        }

        if (textField.Text.Length >= numberCount)
        {
            textField.ResignFirstResponder();
        }
    }
}

Finally , you can use it in Xaml :

<ProjectNameSpace:CustomEntry x:Name="customEntry" WidthRequest="300" />

The effect :

enter image description here