Методы делегата UITextField не запускаются при программной установке текста

Я создал собственное представление ввода для ввода текста в UITextField. По сути, это просто специально разработанная цифровая клавиатура. У меня есть текстовые поля, для которых я установил свойство inputView для использования моего созданного пользователем подкласса UIView. В этом представлении у меня есть набор кнопок - от 0 до 9, а также Backspace.

Теперь я хочу программно изменить текст UITextField при нажатии этих кнопок. UITextField принимает UITextInput протокол, который, в свою очередь, принимает UIKeyInput. В этом протоколе у ​​меня есть все необходимые мне методы, то есть вставка текста в позицию курсора и удаление текста.

Проблема в том, что эти методы не запускают UITextField методов делегата. То есть, например, если у меня есть пользовательская проверка в поле textField:shouldChangeCharactersInRange:replacementString:, это не сработает. Я пытался установить свойство text UITextField напрямую, но это тоже не сработало.

Каков правильный способ вставки текста в UITextField, я имею в виду вставку текста таким образом, чтобы вызывались все методы делегата?


person kyurkchyan    schedule 15.07.2014    source источник
comment
Добавьте свой код, пожалуйста... Если вы используете setText: of UITextField, методы делегата не будут вызываться.   -  person Ryan    schedule 15.07.2014
comment
Я думаю, что это покрывает это: stackoverflow.com/questions/15140087/   -  person trojanfoe    schedule 15.07.2014
comment
Я думаю, что в коде нет необходимости, потому что это всего лишь одна строка — textField.text = @myText; И да, он не вызывает делегата, как я сказал в своем вопросе, поэтому я задаю вопрос, чтобы найти обходной путь.   -  person kyurkchyan    schedule 15.07.2014
comment
trojanfoe, к сожалению, это не так. Я пробовал примеры, но методы делегата по-прежнему не срабатывают.   -  person kyurkchyan    schedule 15.07.2014
comment
Хорошо, вы знаете текст, который вы вставляете, поэтому вы должны иметь возможность проверить его перед вставкой, что устраняет необходимость в делегате. Не похоже на очень сложную проблему.   -  person trojanfoe    schedule 15.07.2014
comment
Нет, не сложно. НО! Я использую настраиваемый элемент управления вводом, который должен быть универсальным. Не привязан к определенному текстовому полю. На самом деле я могу вызвать textField:shouldChangeCharactersInRange:replacementString: вручную, и если он возвращает true, только тогда измените текст. Но я хотел не вмешиваться в поток метода делегата, а просто установить и текст и позволить платформе автоматически вызывать метод делегата, как если бы текст был изменен через клавиатуру по умолчанию. Я знаю, что в iOS 8 поддержка клавиатуры лучше, но мне нужно сделать это в iOS 7.   -  person kyurkchyan    schedule 15.07.2014
comment
Вы установили делегата этого UITextFields?   -  person Viraj Padsala    schedule 19.01.2016
comment
Есть ли у вас какое-либо решение для запуска методов UITextFieldDelegate при программной установке текста? Я пробовал insertText:, а также [textFiled sendActionsForControlEvents:UIControlEventEditingChanged];. Ни один из этих способов не вызывает textField:shouldChangeCharactersInRange:replacementString: в iOS 11.   -  person Aravind G S    schedule 04.01.2018


Ответы (3)


Установите текст UITextField, вызвав insertText:

aTextField.insertText(" ")
person David Lindsay    schedule 25.10.2016
comment
@Alexey на самом деле не должен, потому что это также не вызовет методы делегата - person uneven; 10.05.2018

Я пытался использовать textField:shouldChangeCharactersInRange:replacementString:безуспешно. Я продолжал сталкиваться со сбоем «неверный селектор, отправленный в экземпляр», когда пытался вызвать этот метод.

Я также пытался вызвать события редактирования, но так и не достиг точки останова в моем переопределении ShouldChangeText моего UITextFieldDelegate.

Я решил создать вспомогательный метод, который либо вызывал бы делегат текстового поля (если он существует), либо виртуальный метод ShouldChangeCharacters; и на основе того, что возвращает true или false, затем изменит Text.

Я использую 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;
    }
}
person Kris Coleman    schedule 12.09.2016

self.textfield.delegate = self;
    [self.textfield addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

/* Поместите свой объект контроллера представления вместо себя, когда методы делегата находятся в другом классе */

/* удаление текстового поля вызывается при изменении вида */

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

Как и этот метод, вы также хотите создавать собственные методы.

person Niketan Patel    schedule 19.01.2016