【问题标题】:UITextField delegate methods are not fired when setting text programmatically以编程方式设置文本时不会触发 UITextField 委托方法
【发布时间】:2014-07-15 08:49:35
【问题描述】:

我创建了一个自定义输入视图,用于在UITextField 中输入文本。基本上它只是定制设计的数字键盘。我有文本字段,我在其上设置了 inputView 属性以使用我自定义创建的UIView 子类。在那个视图中,我收集了从 0 到 9 的按钮以及退格键。

现在我想在点击这些按钮时以编程方式更改 UITextField 的文本。 UITextField采用UITextInput协议,而后者又采用UIKeyInput协议。在该协议中,我拥有我需要的所有方法,即将文本插入光标位置并删除文本。

问题是这些方法不会触发UITextField 委托方法。也就是说,如果我在 textField:shouldChangeCharactersInRange:replacementString: 字段中进行了自定义验证,那将无法正常工作。我试过直接设置UITextField的text属性,但是也没用。

UITextField 中插入文本的正确方法是什么,我的意思是以调用所有委托方法的方式插入文本?

【问题讨论】:

  • 请添加您的代码...如果您使用的是 UITextField 的 setText:,则不会调用委托方法。
  • 我认为这涵盖了它:stackoverflow.com/questions/15140087/…
  • 我认为不需要代码,因为它只是一行 - textField.text = @"myText";是的,它不像我在问题中所说的那样调用委托,所以我问这个问题以找到解决方法。
  • trojanfoe 不幸的是它没有。我尝试了这些示例,但委托方法仍然没有触发。
  • 好的,您知道要插入的文本,因此您应该能够在插入之前对其进行验证,从而减少对代理的需求。听起来不是一个很难解决的问题。

标签: ios objective-c uitextfield uitextfielddelegate


【解决方案1】:

调用insertText设置UITextField的文本:

aTextField.insertText(" ")

【讨论】:

  • @Alexey 实际上不应该,因为这也不会触发委托方法
  • textField.insertText("Works for me as well!")
【解决方案2】:

我尝试使用textField:shouldChangeCharactersInRange:replacementString:没有运气。当我尝试调用该方法时,我一直遇到“发送到实例的错误选择器”崩溃。

我也尝试引发编辑事件,但我仍然没有在我的 UITextFieldDelegate 的 ShouldChangeText 覆盖中到达断点。

我决定创建一个辅助方法,它可以调用文本字段的委托(如果存在)或虚拟的 ShouldChangeCharacters 方法;并基于返回真或假,然后将更改文本。

我使用的是 Xamarin.iOS,所以我的项目是 C#,但下面的逻辑可以很容易地用 Objective-C 或 Swift 重写。

可以像这样调用:

    var replacementText = MyTextField.Text + " some more text";
MyTextField.ValidateAndSetTextProgramatically(replacementText);

扩展助手类:

/// <summary>
/// A place for UITextField Extensions and helper methods. 
/// </summary>
public static class UITextFieldExtensions
{
    /// <summary>
    /// Sets the text programatically but still validates
    /// When setting the text property of a text field programatically (in code), it bypasses all of the Editing events. 
    /// Set the text with this to use the built-in validation.
    /// </summary>
    /// <param name="textField">The textField you are Setting/Validating</param>
    /// <param name="replacementText">The replacement text you are attempting to input. If your current Text is "Cat" and you entered "s", your replacement text should be "Cats"</param>
    /// <returns></returns>
    public static bool ValidateAndSetTextProgramatically(this UITextField textField, string replacementText)
    {
        // check for existing delegate first. Delegate should override UITextField virtuals
        // if delegate is not found, safe to use UITextField virtual
        var shouldChangeText = textField.Delegate?.ShouldChangeCharacters(textField, new NSRange(0, textField.Text.Length), replacementText)
                               ?? textField.ShouldChangeCharacters(textField, new NSRange(0, textField.Text.Length), replacementText);
        if (!shouldChangeText)
            return false;

        //safe to update if we've reached this far
        textField.Text = replacementText;
        return true;
    }
}

【讨论】:

    【解决方案3】:
    self.textfield.delegate = self;
        [self.textfield addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
    

    /* 当委托方法在另一个类中时,将您的视图控制器对象改为 self */

    /* textfield delagete 在文本视图发生变化时调用 */

    -(void)textFieldDidChange:(UITextField *)textView
    {
        if(Condition You want to put)
        {
            //Code
        }
        else
        {
            //Code
        }
    }
    

    与此方法一样,您也想制作自定义方法。

    【讨论】:

      猜你喜欢
      • 2021-10-18
      • 1970-01-01
      • 1970-01-01
      • 2011-02-22
      • 2018-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多