【问题标题】:Overriding Native Control Method In Custom Renderer在自定义渲染器中覆盖本机控制方法
【发布时间】:2016-11-08 13:33:33
【问题描述】:

我有一个ExtendedEntry 控件,我用它来为每个平台扩展我的Entry 控件的功能。

在我的自定义渲染器中,我可以访问Control 属性,即UITextField。此属性允许我在运行时轻松更改UITextField 的属性。示例:

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

        Control.ClearButtonMode = UITextFieldViewMode.WhileEditing;

        // ...
    }
}

在 iOS 上,我想覆盖 UITextField Control 的 bool BecomeFirstResponder 方法,它是虚拟的,但是,我不能在运行时覆盖这样的类方法。

如何通过自定义渲染器做到这一点?

【问题讨论】:

    标签: xamarin xamarin.forms


    【解决方案1】:

    不确定您实际上想在BecomeFirstResponder 中做什么,但无需创建UITextField 的自定义子类,您可以创建自定义UITextFieldDelegate 并将其分配给UITextField.Delegate属性。

    如果您试图阻止该字段成为第一响应者,您可以使用UITextFieldDelegate.ShouldBeginEditing 返回false,此方法在BecomeFirstResponder 被调用之前调用)并且UITextFieldDelegate.EditingStarted 在@987654331 之后调用@ 被调用:

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

    参考以下链接查看UITextFieldDelegate的所有方法调用的完整顺序/流程:

    参考:https://developer.apple.com/reference/uikit/uitextfielddelegate

    更新:

    这是我如何执行SecureTextEntry 切换/编辑时没有清除字段:

    1) 自定义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) 设置你的 UITextField:

    uiTextField.Delegate = new SecureTextFieldDelegate();
    

    3) Handle Touch of toggle 和/或物理键盘字段 Tabbing:

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

    UITextField.Text 现在应该永远不会清除,除非用户执行 删除

    【讨论】:

    • 我试图阻止 UITextField 在焦点恢复并且用户再次开始编辑时覆盖密码字段(对于密码可见性切换按钮)。这是 Obj-C 解决方案:stackoverflow.com/a/37061759/1090359。我会看看你发布的委托解决方案,看看我能想出什么。
    • @kspearrin 啊...自定义委托是要走的路,除非您使用子类 UITextField...,查看我的更新
    • 我似乎在尝试在自定义渲染器OnElementChangedControl.Delegate = new SecureTextFieldDelegate(); 中连接代理时遇到以下错误。 System.InvalidOperationException: Event registration is overwriting existing delegate. Either just use events or your own delegate: ExtendedEntryRenderer+SecureTextFieldDelegate UIKit.UITextField+_UITextFieldDelegate。我需要先取消注册一些默认委托还是什么?
    猜你喜欢
    • 2023-03-25
    • 2015-06-14
    • 2020-01-24
    • 2017-12-11
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 2016-06-07
    • 2017-08-28
    相关资源
    最近更新 更多