2

I have an ExtendedEntry control that I use to extend functionality of my Entry controls for each platform.

In my custom renderer I have access to the Control property, which is the UITextField. This property allows me to easily change properties of the UITextField during runtime. Example:

public class ExtendedEntryRenderer : EntryRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);

        Control.ClearButtonMode = UITextFieldViewMode.WhileEditing;

        // ...
    }
}

On iOS I want to override the UITextField Control's bool BecomeFirstResponder method, which is virtual, however, I cannot override a class method like this at runtime.

How can I do this from the custom renderer?

kspearrin
  • 10,238
  • 9
  • 53
  • 82

1 Answers1

0

Not sure what you actually want to do within BecomeFirstResponder, but without creating a custom subclass of UITextField, you can create a custom UITextFieldDelegate and assign it to the UITextField.Delegate property.

If you are trying to prevent the field from becoming a first responder, you could use the UITextFieldDelegate.ShouldBeginEditing to return false, this method is called before BecomeFirstResponder is called) and UITextFieldDelegate.EditingStarted is called after BecomeFirstResponder is called:

public class TextFieldDelegate : UITextFieldDelegate
{
    public override bool ShouldBeginEditing(UITextField textField)
    {
        return base.ShouldBeginEditing(textField);
    }

    public override void EditingStarted(UITextField textField)
    {
        base.EditingStarted(textField);
    }
}

Refer to the following link to review the full order/flow of all the method calls of UITextFieldDelegate:

Ref: https://developer.apple.com/reference/uikit/uitextfielddelegate

Update:

Here is how I do the SecureTextEntry toggle / No clear field on edit:

1) Custom UITextFieldDelegate:

public class SecureTextFieldDelegate : UITextFieldDelegate
{
    public override void EditingStarted(UITextField textField)
    {
        if (textField.SecureTextEntry != true)
        {
            var text = textField.Text;
            textField.DeleteBackward();
            textField.InsertText(text);
        }
    }
}

2) Setup your UITextField:

uiTextField.Delegate = new SecureTextFieldDelegate();

3) Handle Touch of toggle and/or physical keyboard field Tabbing:

uiSwitch.ValueChanged += (object sender, EventArgs e) =>
{
    uiTextField.SecureTextEntry = !uiTextField.SecureTextEntry;
    if (uiTextField.SecureTextEntry == true)
    {
        var text = uiTextField.Text;
        uiTextField.DeleteBackward();
        uiTextField.InsertText(text);
    }
};

The UITextField.Text now should never clear unless the user performs a delete

SushiHangover
  • 73,120
  • 10
  • 106
  • 165
  • I am attempting to block the UITextField from overwriting the password field when focus is resumed and a user begins editing again (for a password visibility toggle button). This is the Obj-C solution: http://stackoverflow.com/a/37061759/1090359. I'll have a look at the delegate solution you posted and see what I can come up with. – kspearrin Nov 08 '16 at 04:20
  • @kspearrin Ah...the custom delegate is the way to go unless you are working with a subclassed `UITextField`..., checkout my update – SushiHangover Nov 08 '16 at 05:34
  • I seem to be getting the following error trying to wire up the delegate in the custom renderer `OnElementChanged` `Control.Delegate = new SecureTextFieldDelegate();`. `System.InvalidOperationException: Event registration is overwriting existing delegate. Either just use events or your own delegate: ExtendedEntryRenderer+SecureTextFieldDelegate UIKit.UITextField+_UITextFieldDelegate`. Do I need to unregister some default delegate or something first? – kspearrin Nov 09 '16 at 00:27