Обнаружить обратное пространство в пустом UITextField

126

Есть ли способ определить, когда клавиша Backspace/ Deleteнажата на клавиатуре iPhone на UITextFieldпустом месте? Я хочу знать, когда Backspaceнажимается, только если UITextFieldпусто.


Основываясь на предложении @Alex Reynolds в комментарии, я добавил следующий код при создании своего текстового поля:

[[NSNotificationCenter defaultCenter] addObserver:self
          selector:@selector(handleTextFieldChanged:)
              name:UITextFieldTextDidChangeNotification
            object:searchTextField];

Это уведомление получено ( handleTextFieldChangedфункция вызывается), но все равно не когда я нажимаю Backspaceклавишу в пустом поле. Любые идеи?


Кажется, в этом вопросе есть некоторая путаница. Я хочу получать уведомление при Backspaceнажатии клавиши. Вот и все. Но решение должно работать и тогда, когда UITextFieldон уже пуст.

Marcc
источник
Я думаю, вы могли иметь в виду «только если UITextField пуст», а не «только если клавиатура пуста» ...?
Стив Харрисон,
@ Стив Харрисон: спасибо. Обновил это.
marcc
Я пытаюсь сделать что-то подобное, какое решение у вас тогда получилось? То, что я делаю, - это текстовое поле в режиме прокрутки, когда я набираю текст, отображаются предложения, а когда я щелкаю по нему, объект метки помещается слева от текстового поля. Заранее спасибо: D
Dough
2011/11 решения для пустого UITextField с помощью выполнения фокусов: bjhomer.blogspot.com/2011/11/...
Яно
4
До смешного хочется чего-то столь тривиального. Это не должно быть трудным.
Адам Уэйт

Ответы:

36

Это может быть маловероятно, но это может сработать. Попробуйте установить для текста текстового поля символ пробела нулевой ширины \u200B. Когда в текстовом поле, которое кажется пустым, нажата клавиша Backspace, оно фактически удаляет ваше пространство. Затем вы можете просто вставить пространство заново.

Может не работать, если пользователю удастся переместить курсор влево от места.

Андрей
источник
3
@ Андрей, я решил применить именно такой подход. Потребовалось немного кода, но он, безусловно, эффективен. Спасибо за помощь, а не пытаюсь сказать мне, что я что-то делаю не так.
marcc 02
2
Этот метод может работать на iPhone> 3.1.3, но он хакерский и может сломаться в будущих версиях и т. Д. Я думаю, что нашел более чистое и стабильное решение для определения нажатия клавиши удаления на клавиатуре на iPhone / iOS .
ma11hew28 09
6
Я могу подтвердить, что удаление не обнаруживается, если пользователю удается переместить курсор влево от места. Если вы можете выяснить , как исправить это, то вы должны также подкласс UITextFieldи реализовать canPerformAction:withSender:в return NOтечение select:и selectAll:действий , если текст равна строке @"\u200B".
ma11hew28
2
Проблема в том, что это не работает для защищенных тестовых полей. Есть идеи, как с этим справиться?
Кайл Клегг
7
Извините, но это плохая идея. Это невероятно хакерский и не должен быть принятым ответом с 30 или около того голосами. Вместо этого я бы создал подкласс UITextField, как упоминали некоторые другие комментаторы.
Брайан Сачетта,
155

Swift 4:


Подкласс UITextField:

// MyTextField.swift
import UIKit

protocol MyTextFieldDelegate: AnyObject {
    func textFieldDidDelete()
}

class MyTextField: UITextField {

    weak var myDelegate: MyTextFieldDelegate?

    override func deleteBackward() {
        super.deleteBackward()
        myDelegate?.textFieldDidDelete()
    }

}

Реализация:

// ViewController.swift

import UIKit

class ViewController: UIViewController, MyTextFieldDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // initialize textField
        let input = MyTextField(frame: CGRect(x: 50, y: 50, width: 150, height: 40))

        // set viewController as "myDelegate"
        input.myDelegate = self

        // add textField to view
        view.addSubview(input)

        // focus the text field
        input.becomeFirstResponder()
    }

    func textFieldDidDelete() {
        print("delete")
    }

}

Objective-C:


Подкласс UITextField:

//Header
//MyTextField.h

//create delegate protocol
@protocol MyTextFieldDelegate <NSObject>
@optional
- (void)textFieldDidDelete;
@end

@interface MyTextField : UITextField<UIKeyInput>

//create "myDelegate"
@property (nonatomic, assign) id<MyTextFieldDelegate> myDelegate;
@end

//Implementation
#import "MyTextField.h"

@implementation MyTextField

- (void)deleteBackward {
    [super deleteBackward];

    if ([_myDelegate respondsToSelector:@selector(textFieldDidDelete)]){
        [_myDelegate textFieldDidDelete];
    }
}

@end

Теперь просто добавьте MyTextFieldDelegate в ваш UIViewControllerи установите UITextFields myDelegate на self:

//View Controller Header
#import "MyTextField.h"

//add "MyTextFieldDelegate" to you view controller
@interface ViewController : UIViewController <MyTextFieldDelegate>
@end

//View Controller Implementation
- (void)viewDidLoad {
    //initialize your text field
    MyTextField *input = 
     [[MyTextField alloc] initWithFrame:CGRectMake(0, 0, 70, 30)];

    //set your view controller as "myDelegate"
    input.myDelegate = self;

    //add your text field to the view
    [self.view addSubview:input];
}

//MyTextField Delegate
- (void)textFieldDidDelete {
    NSLog(@"delete");
}
Джекоб
источник
9
Это лучшее решение. Принятый ответ - взлом. Цель C основана на подклассах, и это решение использует ее должным образом для решения проблемы.
TJ
Что произойдет с моими существующими методами делегата в ViewController классе, если я установлю делегат текстового поля на подкласс UITextFieldвместоUIViewController
rohan-patel
4
По-видимому, сейчас это не работает в ios8 из-за того, что похоже на ошибку
chug2k
1
Я использовал обходное решение для ошибки ios8, как в моем ответе, и оно сработало. Это может быть полезно тем, кто ищет решение.
furkan3ayraktar
1
deleteBackward()не будет вызываться , если вам return falseвtextField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
igrrik
41

Обновление: см . Ответ JacobCaraballo для примера, который отменяет -[UITextField deleteBackward].

Проверьте UITextInput, в частности, UIKeyInputесть deleteBackwardметод делегата, который всегда вызывается при нажатии клавиши удаления. Если вы делаете что-то простое, вы можете просто UILabelсоздать подкласс и привести его в соответствие с UIKeyInputпротоколом, как это сделано с помощью SimpleTextInput и этого примера iPhone UIKeyInput . Примечание: UITextInputи его родственники (в том числе UIKeyInput) доступны только в iOS 3.2 и новее.

ma11hew28
источник
2
Это правильный ответ. Это не взломано и очень просто с быстрым подклассом UITextField.
Сэм
Только что заметил ответ Джейкоба ниже. Он дает подробный пример этого.
Сэм
Стоит отметить, что этот ответ не работает в iOS 5. Если текстовое поле пусто, нажатие клавиши Backspace не вызывает этот метод.
jfeldman
31

Код, подобный следующему:

@interface MyTextField : UITextField
@end

@implementation MyTextField

- (void)deleteBackward
{
    [super deleteBackward];

    //At here, you can handle backspace key pressed event even the text field is empty
}

@end

Наконец, не забудьте изменить свойство Custom Class текстового поля на MyTextField.

Джеффри Лу
источник
5
Это должен быть принятый ответ. Чисто и собственно отвечает на вопрос.
Райан Романчук
1
Он отвечает на вопрос ... Пока вы ориентируетесь на iOS 6.0+. К сожалению, в iOS 5 функция deleteBackward никогда не вызывалась в вашем подклассе.
BJ Homer
2
Б. Дж. Гомер, 93% устройств работают на iOS 6, поэтому отказ от ориентации на iOS 5, как правило, не представляет большого труда.
Джонатан.
2
Я рад, что пролистал достаточно, чтобы найти это. 100% правильный способ сделать это сегодня в IOS 7.
MusiGenesis 01
Я видел так много других ответов на этот вопрос, которые являются просто обходными путями, и вряд ли какой-либо из них связан с ситуацией, когда клавиша Backspace нажата в пустом поле. Однако это идеальный и действительно чистый способ сделать это.
Кристофер Ханна,
19

Быстрая реализация:

import UIKit

protocol PinTexFieldDelegate : UITextFieldDelegate {
    func didPressBackspace(textField : PinTextField)
}

class PinTextField: UITextField {

    override func deleteBackward() {
        super.deleteBackward()

        // If conforming to our extension protocol
        if let pinDelegate = self.delegate as? PinTexFieldDelegate {
            pinDelegate.didPressBackspace(self)
        }
    }
}
Рууд Виссер
источник
Спасибо, могу ли я узнать, что этот метод рекомендован Apple или это взлом. это кажется недокументированным для текстового поля.
kalpesh jetani
Работал у меня с textView. спасибо, что поделились;)
Эдуард Барбье
Работал для меня, когда текстовое поле пусто, а заднее пространство нажато.
Рамакришна
17

Я нашел другой способ проще, чем subclassрешение. Даже немного странно, но работает нормально.

- (BOOL)textView:(UITextView *)textView 
        shouldChangeTextInRange:(NSRange)range 
        replacementText:(NSString *)text
{
    const char * _char = [text cStringUsingEncoding:NSUTF8StringEncoding];
    int isBackSpace = strcmp(_char, "\b");

    if (isBackSpace == -8) {
       // is backspace
    }

    return YES;
}

Немного странно, результат сравнения -8. Может, в чем-то я ошибаюсь C Programming. Но его правильная работа;)

Джерапонг Нампетч
источник
1
Для плавания на спине не задан '\ b'. Но если вы внимательно отлаживаете, вы увидите '\ 0'. Итак, я получаю результат 0, то есть два значения равны в методе strcmp. const char * stoke = [текст cStringUsingEncoding: NSASCIIStringEncoding]; const char * backstroke = "\ 0"; // это равно \ b -> "\ x08"; strcmp (на спине, ходьбе);
Юн Ли
Кроме того, по определению strcmp (s1, s2) возвращает 0, если s1 == s2,> 0 s1 лексикографически больше, чем s2, наоборот.
Юн Ли
Я не понимаю, как это могло работать? @YoonLee: ты тоже не говоришь о strcmpвозврате -1, 0, or 1? Это было моим пониманием.
chug2k
1
в текстовом представлении вы всегда обнаруживаете обратное пространство, даже если текста нет, UITextField отличается
LolaRun
2
Это не UITextViewDelegateметод UITextFieldDelegate.
pkamb
12

Попробуйте delegate

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string {

Затем проверьте, range.length == 1похоже ли это на то, что происходит при backspaceударе.

Никлас Альвеус
источник
8
Однако вызывается только тогда, когда поле не пустое. Обратите внимание на исходный вопрос. :)
Эрик Голдберг
Используйте для этого UITextView.
Олег
11

пожалуйста, используйте приведенный ниже код, это поможет вам обнаружить клавишу удаления клавиатуры, даже если текстовое поле пусто.

Цель C:

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField { return YES; }

Swift:

func keyboardInputShouldDelete(_ textField: UITextField) -> Bool { return true }
Pritesh
источник
Tx - как раз то, что мне нужно. Но где это задокументировано ??
Энди Вайнштейн,
9

Ответ Никласа Альвеуса помог мне с аналогичной проблемой

Я ограничивал ввод определенным набором символов, но игнорировал обратные пробелы. Так что я проверил его range.length == 1перед обрезкой NSString. Если это правда, я просто возвращаю строку и не обрезаю ее. Увидеть ниже

 - (BOOL) textField:(UITextField *)textField 
          shouldChangeCharactersInRange:(NSRange)range 
          replacementString:(NSString *)string
 {
     NSCharacterSet *nonNumberSet = 
      [[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] 
         invertedSet];

    if (range.length == 1) {
       return string;
    }
    else {
       return ([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0);
    }   
 }
Бен Колл
источник
Метод ожидает в качестве возвращаемого значения логическое значение, а не строку
Паскалиус
4

Для тех, у кого есть проблемы с ответом Джейкоба, я реализовал свой подкласс текстового поля следующим образом, и он отлично работает!

#import <UIKit/UIKit.h>

@class HTTextField;

@protocol HTBackspaceDelegate <NSObject>

@optional
- (void)textFieldDidBackspace:(HTTextField*)textField;
@end

@interface HTTextField : UITextField<UIKeyInput>

@property (nonatomic, assign) id<HTBackspaceDelegate> backspaceDelegate;

@end


#import "HTTextField.h"

@implementation HTTextField

- (void)deleteBackward {
    [super deleteBackward];
    if ([self.backspaceDelegate respondsToSelector:@selector(textFieldDidBackspace:)]){
        [self.backspaceDelegate textFieldDidBackspace:self];
    }
}

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField {
    BOOL shouldDelete = YES;

    if ([UITextField instancesRespondToSelector:_cmd]) {
        BOOL (*keyboardInputShouldDelete)(id, SEL, UITextField *) = (BOOL (*)(id, SEL, UITextField *))[UITextField instanceMethodForSelector:_cmd];

        if (keyboardInputShouldDelete) {
            shouldDelete = keyboardInputShouldDelete(self, _cmd, textField);
        }
    }

    if (![textField.text length] && [[[UIDevice currentDevice] systemVersion] intValue] >= 8) {
        [self deleteBackward];
    }

    return shouldDelete;
}

@end
furkan3ayraktar
источник
вы можете написать код для быстрого. Я получил некоторую ошибку «избыточное подтверждение для протокола uikeyinput»
Радж Аггравал
4

Да, используйте метод ниже, чтобы обнаружить обратное пространство, когда textField пуст.

Необходимо добавить UITextFieldDelegate

yourTextField.delegate = self (НЕОБХОДИМО)

Swift:

func keyboardInputShouldDelete(_ textField: UITextField) -> Bool { 
    return true
}

Цель C:

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField { 
    return YES; 
}
Химаншу падиа
источник
5
Это даже не требует меня. Все другие методы делегата вызываются по мере возникновения события.
Hemang
Спасибо, дружище .. Ты справился. :)
ср.
@ McDonal_11 Я думаю, вы забыли установить textfield.delegate = self текстового поля.
Химаншу падиа
Я установил. другие методы делегата UITextField работают нормально. Только этот не работает. Что я скучаю ??
McDonal_11
3

Лучшее использование, которое я нашел для обнаружения обратного пространства, - это обнаружение, когда пользователь нажал клавишу возврата в пустом месте UITextField. Например, если в почтовом приложении есть «пузырьковые» получатели, когда вы нажимаете клавишу Backspace в UITextField, он выбирает последнего «пузырькового» получателя.

Это можно сделать аналогично ответу Джейкоба Карабальо. Но в ответе Джейкоба, если у UITextFieldнего остался один символ, когда вы нажмете backspace, к тому времени, когда будет получено сообщение делегата, UITextFieldбудет уже пустым, поэтому вы эффективно обнаруживаете backspaceтекстовое поле с не более чем одним символом.

На самом деле, если вы хотите обнаружить backspaceна a UITextFieldс точно нулевым количеством символов (пустым), вы должны отправить сообщение delegateдо вызова super deleteBackward. Например:

#import "MyTextField.h"

//Text field that detects when backspace is hit with empty text
@implementation MyTextField

#pragma mark - UIKeyInput protocol
-(void)deleteBackward
{
  BOOL isTextFieldEmpty = (self.text.length == 0);
  if (isTextFieldEmpty) {
    if ([self.delegate 
         respondsToSelector:@selector(textFieldDidHitBackspaceWithEmptyText:)]) {

        [self.delegate textFieldDidHitBackspaceWithEmptyText:self];
        }
    }
    [super deleteBackward];
}
@end

Интерфейс такого текстового поля будет выглядеть примерно так:

@protocol MyTextFieldDelegate;

@interface MyTextField : UITextField
@property(nonatomic, weak) id<MyTextFieldDelegate> delegate;
@end

@protocol MyTextFieldDelegate <UITextFieldDelegate>
@optional
-(void)textFieldDidHitBackspaceWithEmptyText:(MyTextField *)textField;
@end
Сэм
источник
2
Чтобы это работало в iOS8 (где есть ошибка, из-за которой этот метод делегата никогда не вызывается), см. Этот ответ: stackoverflow.com/a/25862878/893101 . Подробнее об ошибке ios8: devforums.apple.com/message/1009150#1009150
pIkEL
2

В iOS 6 метод deleteBackward вызывается в UITextField при нажатии кнопки Backspace, в том числе когда поле пусто. Таким образом, вы можете создать подкласс UITextField и предоставить свою собственную реализацию deleteBackward (также вызывая super).

Я все еще поддерживаю iOS 5, поэтому мне понадобится комбинация ответа Эндрю и этого.

Tracy
источник
1

:) только для заголовка "Обнаружить обратное пространство", где я использую UIKeyboardTypeNumberPad .

Сегодня вечером я также встречаю тот же вопрос, и вот мой код, чтобы узнать его:

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string
{
    NSLog([NSString stringWithFormat:@"%d", [string length]]);
}

Потому что с UIKeyboardTypeNumberPad , пользователь может вводить только Number или backspace, поэтому, когда длина строки равна 0, это должна быть клавиша backspace.

Надеюсь, что это поможет.

Джейсон Ли
источник
То же самое с любым типом клавиатуры.
ma11hew28
как подключить этот метод к моему текстовому полю?
user230910
1

Вместо того, чтобы пытаться заранее сконструировать, что БУДЕТ в текстовом поле, или выяснить, какой специальный символ был введен в shouldChangeCharactersInRangeметод, я бы предложил сделать следующее:

[self performSelector:@selector(manageSearchResultsDisplay) 
           withObject:nil 
           afterDelay:0];

Это позволяет вам вызывать метод сразу после завершения текущей операции. Что в этом круто, так это то, что к моменту его завершения измененное значение уже будет в UITextField. На этом этапе вы можете просто проверить его длину и / или подтвердить, исходя из того, что там есть.

Аарон
источник
1

Создание подклассов UITextField у меня не работало на iOS 8.3, deleteBackward никогда не вызывался.

Вот решение, которое я использовал, работает на всех версиях iOS 8 и также должно работать на других версиях iOS.

for textField in textFields {
            textField.text = " "
}

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        if string == "" && textField.text == " "   {
            // Do stuff here
            return false
        }
        return true
}
joel.d
источник
1

В файле .h добавьте делегата UIKeyInput

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField {

if ([textField isEqual:_txtFirstDigit]) {

}else if([textField isEqual:_txtSecondDigit]) {
    [_txtFirstDigit becomeFirstResponder];

}else if([textField isEqual:_txtThirdDigit]) {
    [_txtSecondDigit becomeFirstResponder];

}else if([textField isEqual:_txtFourthDigit]) {
    [_txtThirdDigit becomeFirstResponder];
}
return YES;
}   

улучшенное форматирование

Анджали Прасад
источник
1

Я реализовал аналогичное решение с небольшими улучшениями, которые сообщают мне, имеет ли текстовое поле какое-либо значение, когда пользователь нажал на обратное пространство. Это полезно для моего случая, когда я должен сосредоточиться только на другом текстовом поле, если текстовое поле пусто при нажатии кнопки возврата.

protocol MyTextFieldDelegate : UITextFieldDelegate {
    func textFieldDidDelete(textField: MyTextField, hasValue: Bool)
}

override func deleteBackward() {
    let currentText = self.text ?? ""
    super.deleteBackward()
    let hasValue = currentText.isEmpty ? false : true
    if let delegate = self.delegate as? MyTextFieldDelegate {
        delegate.textFieldDidDelete(textField: self, hasValue: hasValue)
    }
}
Hemang
источник
1

Самый топичный ответ упускает одну вещь - возможность определить, было ли текстовое поле пустым или нет.

То есть, когда вы переопределяете метод deleteBackwards () подкласса TextField, вы все равно не знаете, было ли текстовое поле уже пустым. (И до, и после deleteBackwards () textField.text!это пустая строка:"" )

Вот мое улучшение, с проверкой на пустоту перед удалением.

1. Создайте протокол делегата, который расширяет UITextFieldDelegate.

protocol MyTextFieldDelegate: UITextFieldDelegate {
    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool)
}

2. Подкласс UITextField

class MyTextField: UITextField {
    override func deleteBackward() {
        // see if text was empty
        let wasEmpty = text == nil || text! == ""

        // then perform normal behavior
        super.deleteBackward()

        // now, notify delegate (if existent)
        (delegate as? MyTextFieldDelegate)?.textField(self, didDeleteBackwardAnd: wasEmpty)
    }
}

3. Внедрите новый протокол делегата.

extension MyViewController: MyTextFieldDelegate {
    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool) {
        if wasEmpty {
            // do what you want here...
        }
    }
}
Тим
источник
1

Комплексный обработчик текстового поля с однозначным номером для Swift 5.1 :

  • Предполагая, что у вас есть коллекция выходных текстовых полей (также с подключенными делегатами)

1 шаг

protocol MyTextFieldDelegate: class {
    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool) 
}

final class MyTextField: UITextField {

    weak var myDelegate: MyTextFieldDelegate?

    override func deleteBackward() {
        let wasEmpty = text == nil || text == ""

        // then perform normal behavior
        super.deleteBackward()

        // now, notify delegate (if existent)
        (delegate as? MyTextFieldDelegate)?.textField(self, didDeleteBackwardAnd: wasEmpty)
    }
}

2 шаг

final class ViewController: UIViewController {

    @IBOutlet private var textFields: [MyTextField]!

    override func viewDidLoad() {
        super.viewDidLoad()
        textFields.forEach {
            $0.delegate = self
            $0.myDelegate = self
        }
    }
}

3 шаг

extension ViewController: UITextFieldDelegate, MyTextFieldDelegate {
    func textFieldHasChanged(with text: String, _ tag: Int, for textField: UITextField) {
        textField.text = text

        if let someTextField = (textFields.filter { $0.tag == tag }).first {
            someTextField.becomeFirstResponder()
        } else {
            view.endEditing(true)
        }
    }

    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool) {
        // If the user was pressing backward and the value was empty, go to previous textField
        textFieldHasChanged(with: "", textField.tag - 1, for: textField)
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // Restrict to only digits
        let aSet = NSCharacterSet(charactersIn: "0123456789").inverted
        let compSepByCharInSet = string.components(separatedBy: aSet)
        let numberFiltered = compSepByCharInSet.joined(separator: "")

        guard string == numberFiltered, let text = textField.text else { return false }

        if text.count >= 1 && string.isEmpty {
            // If the user is deleting the value
            textFieldHasChanged(with: "", textField.tag - 1, for: textField)
        } else {
            textFieldHasChanged(with: string, textField.tag + 1, for: textField)
        }

        return false
    }
}
Latenec
источник
0

Вот мое решение, основанное на идее @andrew:

где-нибудь например в viewDidLoad

        textField.delegate = self
        textField.addTarget(self, action: #selector(valueChanged(_:)), for: .editingDidBegin)

а потом

    @objc func valueChanged(_ textField: UITextField) {
        textField.text = "\u{200B}"
    }

    override func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        textField.text = string
        if string == "" {
            //backpaspace pressed 
        }
rastislv
источник
0

Вы можете проверить текст текстового представления / поля, чтобы убедиться, что он пуст, и убедиться, что замещающий текст также пуст в методе делегата shouldChangeTextIn.

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if (textView.text == "" && text == "") {
        print("Backspace on empty text field.")
    }
    return true
}
майкл-K101
источник
-2

Что-то вроде этого:

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string       
{  
    if (![text hash] && ![textField.text length])  
        [self backspaceInEmptyTextField];  
}

конечно, хеш для одной символьной строки.

user1375355
источник
-2

Используя метод делегата TextField:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

Добавьте следующий код в метод выше, чтобы обнаружить событие удаления

if(textField == YourTextField)
{
    if ([string length] == 0 && range.length > 0)
    {
        // Your Code after deletion of character
    }
}
Калим Сайяд
источник
-3

Чтобы не усложнять, вот единственное условие, которое вам нужно проверить

     if (range.length==1)
Бхумит Мехта
источник
-3
+ (BOOL)detectBackspaceOnly:(NSString *)string
{
    for(int i=0 ; i<string.length ; i++){
        unichar caract = [string characterAtIndex:i];
        if(caract != ' ' && caract != '\n')
            return NO;
    }

    return YES;
}
K-AnGaMa
источник
2
Может быть, небольшое пояснение, куда это поставить?
Alex Cio
-4

В UITextViewDelegate:

- (BOOL)               textView:(UITextView *)textView 
        shouldChangeTextInRange:(NSRange)range 
                replacementText:(NSString *)text
{
    if(text isEqualToString:@"");
    {
        NSLog(@"press backspace.");
    }
}

у меня работает нормально.

обновление для упрощенного китайского пиньинь и китайского рукописного ввода:

- (BOOL)               textView:(UITextView *)textView 
        shouldChangeTextInRange:(NSRange)range 
                replacementText:(NSString *)text
{
    if (range.length > 0 && [text isEqualToString:@""]) {
        NSLog(@"press Backspace.");
    }
    return YES;
}

на основании документа сказано:

«Если пользователь нажимает deleteKey, длина диапазона равна 1, и пустой строковый объект заменяет этот единственный символ».

джокер
источник
1
Это вопрос UITextField, а не о UITextView.
ma11hew28