Detectar backspace no UITextField vazio

126

Existe alguma maneira de detectar quando a tecla Backspace/ Deleteé pressionada no teclado do iPhone em um UITextFieldque está vazio? Quero saber quando Backspaceé pressionado apenas se o UITextFieldestiver vazio.


Com base na sugestão de @Alex Reynolds em um comentário, adicionamos o seguinte código ao criar meu campo de texto:

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

Essa notificação é recebida (a handleTextFieldChangedfunção é chamada), mas ainda não é quando pressiono a Backspacetecla em um campo vazio. Alguma ideia?


Parece haver alguma confusão em torno dessa questão. Quero receber uma notificação quando a Backspacetecla for pressionada. É isso aí. Mas a solução também deve funcionar quando a UITextFieldjá estiver vazia.

marcc
fonte
Eu acho que você pode querer dizer "apenas se o UITextField estiver vazio" em vez de "apenas se o teclado estiver vazio" ...?
Steve Harrison
@ Steve Harrison: obrigado. Atualizado isso.
Marcc 30/12/2009
Estou tentando fazer algo parecido, que solução você conseguiu então? O que estou fazendo é um campo de texto em uma exibição de rolagem, quando digito algum texto, são exibidas sugestões e quando clico em um, um objeto de rótulo é colocado à esquerda do campo de texto. Agradecemos antecipadamente: D
Dough
Solução 2011/11 para o UITextField vazio usando truques de tempo de execução: bjhomer.blogspot.com/2011/11/…
Jano
4
Ridiculamente longo para algo tão trivial. Isso não deve ser difícil.
Adam Waite

Respostas:

36

Isso pode ser um tiro no escuro, mas pode funcionar. Tente definir o texto do campo de texto como um caractere de espaço com largura zero \u200B. Quando o backspace é pressionado em um campo de texto que parece vazio, na verdade ele exclui seu espaço. Então você pode apenas reinserir o espaço.

Pode não funcionar se o usuário conseguir mover o cursor para a esquerda do espaço.

Andrew
fonte
3
@ Andrew, esta é a abordagem que decidi adotar. Demorou um pouco de código, mas certamente é eficaz. Obrigado pela ajuda, em vez de tentar me dizer que estou fazendo algo errado.
Marcc
2
Essa técnica pode funcionar no iPhone> 3.1.3, mas é hacky e pode quebrar em versões futuras, etc. Acho que encontrei uma solução mais limpa e mais estável de como detectar um pressionamento de tecla de exclusão no iPhone / iOS .
ma11hew28
6
Posso confirmar que a exclusão não é detectada se o usuário conseguir mover o cursor para a esquerda do espaço. Se você pode descobrir como consertar isso, então você também deve subclasse UITextFielde implementar canPerformAction:withSender:a return NOpara select:e selectAll:ações quando o texto é igual à cadeia @"\u200B".
ma11hew28
2
O problema é que isso não funciona para campos de teste seguros. Alguma idéia de como lidar com isso?
Kyle Clegg
7
Desculpe, mas essa ideia é ruim. É hacky incrível e não deve ser a resposta aceita com mais de 30 votos. Eu subclassificaria UITextField, como alguns dos outros comentaristas mencionaram.
Brian Sachetta
155

Swift 4:


Subclasse UITextField:

// MyTextField.swift
import UIKit

protocol MyTextFieldDelegate: AnyObject {
    func textFieldDidDelete()
}

class MyTextField: UITextField {

    weak var myDelegate: MyTextFieldDelegate?

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

}

Implementação:

// 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")
    }

}

Objetivo-C:


Subclasse 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

Agora basta adicionar MyTextFieldDelegate ao seu UIViewControllere defina seu UITextFields myDelegate como 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");
}
jacob
fonte
9
essa é a melhor solução. A resposta aceita é um hack. O objetivo C é baseado na subclassificação e esta solução o utiliza adequadamente para resolver o problema.
TJ
O que acontecerá com meus métodos de delegado existentes em ViewController classe se eu definir delegado do meu campo de texto para subclasse de UITextField, em vez deUIViewController
rohan-patel
4
Isto aparentemente não funciona em iOS8 agora, devido ao que parece ser um Apple Bug: devforums.apple.com/message/1045312#1045312
chug2k
1
Eu usei uma solução alternativa para bug ios8 como na minha resposta e funcionou. Pode ser útil para quem está procurando uma solução.
furkan3ayraktar
1
deleteBackward()não será chamado se você return falsetextField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
entrar
41

Atualização: Veja a resposta de JacobCaraballo para um exemplo que substitui -[UITextField deleteBackward].

Confira UITextInput, especificamente, UIKeyInputtem um deleteBackwardmétodo delegado que sempre é chamado quando a tecla Delete é pressionada. Se você estiver fazendo algo simples, considere apenas subclassificar UILabele torná-lo em conformidade com o UIKeyInputprotocolo, conforme feito por SimpleTextInput e por este exemplo de UIKeyInput do iPhone . Nota: UITextInpute seus parentes (inclusive UIKeyInput) estão disponíveis apenas no iOS 3.2 e posterior.

ma11hew28
fonte
2
Esta é a resposta certa. É não-hacky e muito simples, com uma subclasse rápida do UITextField.
Sam
Apenas localizei a resposta de Jacob abaixo. Ele fornece um exemplo detalhado disso.
Sam
Vale ressaltar que esta resposta não funciona no iOS 5. Se o campo de texto estiver vazio, pressionar backspace não invocará esse método.
jfeldman
31

Código como a seguir:

@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

Por fim, esqueça de alterar a propriedade Custom Class do campo de texto para "MyTextField"

Jeffrey Loo
fonte
5
Essa deve ser a resposta aceita. Limpo, e realmente responde à pergunta.
Ryan Romanchuk
1
Ele responde à pergunta ... Desde que você tenha como alvo o iOS 6.0 ou superior. Infelizmente, no iOS 5, deleteBackward nunca foi chamado em sua subclasse.
BJ Homer
2
BJ Homer, 93% dos dispositivos estão no iOS 6, portanto, não ter como alvo o iOS 5 geralmente não é um problema.
Jonathan.
2
Fico feliz por continuar rolando o suficiente para encontrar isso. 100% o caminho certo para fazer isso hoje em IOS 7.
MusiGenesis
Eu já vi muitas outras respostas para essa pergunta que são apenas soluções alternativas e quase nenhuma delas lida com a situação em que a tecla backspace é pressionada em um campo vazio. No entanto, isso é perfeito e uma maneira realmente limpa de fazer isso.
9609 Christopher Plummer
19

Implementação rápida:

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)
        }
    }
}
Ruud Visser
fonte
Obrigado, posso saber que este método é recomendado pela Apple ou é hack. parece indocumentado para o campo de texto.
kalpesh jetani
Trabalhou para mim com um textView. obrigado por compartilhar;)
Edouard Barbier
Funcionou para mim quando o campo de texto está vazio e o espaço para trás é clicado.
Ramakrishna
17

Eu fundei de outra maneira mais fácil do que subclasssolução. Mesmo um pouco estranho, mas funciona bem.

- (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;
}

É um pouco estranho, pois o resultado da comparação é -8. Talvez eu esteja errado em algum momento C Programming. Mas o seu trabalho certo;)

Jerapong Nampetch
fonte
1
A sequência de costas não está '\ b' definida. Mas se você depurar cuidadosamente, verá '\ 0'. Então, eu obtenho o resultado 0, ou seja, dois valores são iguais no método strcmp. const char * stoke = [texto cStringUsingEncoding: NSASCIIStringEncoding]; const char * backstroke = "\ 0"; // é igual a \ b -> "\ x08"; strcmp (costas, toque);
Yoon Lee
Além disso, pela definição de strcmp (s1, s2), retorna 0 se s1 == s2,> 0 s1 é lexicograficamente maior que s2 vice-versa.
Yoon Lee
Eu não entendo como isso poderia funcionar? @YoonLee: você também não está dizendo strcmpdevoluções -1, 0, or 1? Essa foi a minha compreensão.
chug2k
1
em textview você sempre detectar o backspace mesmo que o não há nenhum texto, o UITextField é diferente
LolaRun
2
Este é um UITextViewDelegatemétodo, não UITextFieldDelegate.
Pkamb 29/11/16
11

Tente o delegate

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

Em seguida, verifique se o range.length == 1que parece ser o caso quando backspaceé atingido.

Niklas Alvaeus
fonte
8
Apenas chamado quando o campo não está vazio, no entanto. Observe a pergunta original. :)
Eric Goldberg
Use UITextView para isso.
21413 Oleg
11

use o código abaixo para ajudá-lo a detectar a tecla de exclusão do teclado, mesmo se o campo de texto estiver vazio.

Objetivo C:

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

Rápido :

func keyboardInputShouldDelete(_ textField: UITextField) -> Bool { return true }
Pritesh
fonte
Tx - exatamente o que eu precisava. Mas onde está documentado?
Andy Weinstein
9

A resposta de Niklas Alvaeus me ajudou com um problema semelhante

Eu estava limitando a entrada para um conjunto de caracteres específico, mas estava ignorando os backspaces. Então eu tive que verificar range.length == 1antes de aparar o NSString. Se for verdade, eu apenas retorno a string e não a corto. Ver abaixo

 - (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);
    }   
 }
Ben Call
fonte
O método espera um booleano e não uma string como valor de retorno
Pascalius
4

Para quem tem problemas com a resposta de Jacob, implementei minha subclasse de campo de texto da seguinte maneira e funciona muito bem!

#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
fonte
você pode escrever o código para swift. Eu recebi algum erro "confirmação redundante para protoco uikeyinput"
Raj Aggrawal
4

Sim, use o método abaixo para detectar backspace, quando textField estiver vazio.

Precisa adicionar UITextFieldDelegate

yourTextField.delegate = self (DEVE NECESSÁRIO)

Rápido:

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

Objetivo C:

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField { 
    return YES; 
}
Himanshu padia
fonte
5
Isso nem me chama. Todos os outros métodos delegados estão sendo chamados quando e quando ocorre um evento.
Hemang
Obrigado companheiro .. Você acertou em cheio :) :)
MS.
@ McDonal_11 Acho que você esqueceu de definir textfield.delegate = self do campo de texto.
Himanshu padia
Eu arrumei. outros métodos de delegação do UITextField estão funcionando bem. Este sozinho não está funcionando. O que eu sinto falta ??
McDonal_11 11/06
3

O melhor uso que encontrei para detectar o backspace é detectar quando o usuário pressionou o backspace em um vazio UITextField. Por exemplo, se você tiver 'borbulhado' nos destinatários do aplicativo de email, ao pressionar backspace no UITextField, ele selecionará o último destinatário 'borbulhado'.

Isso pode ser feito de maneira semelhante à resposta de Jacob Caraballo. Mas na resposta de Jacob, se UITextFieldhouver um caractere quando você pressionar backspace, no momento em que a mensagem do delegado for recebida, UITextFieldela já estará vazia, então você estará efetivamente detectando backspaceem um campo de texto com no máximo um caractere.

Na verdade, se você deseja detectar backspaceem um UITextFieldcom exatamente zero caracteres (vazio), envie a mensagem para delegateantes da chamada super deleteBackward. Por exemplo:

#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

A interface para esse campo de texto seria algo como isto:

@protocol MyTextFieldDelegate;

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

@protocol MyTextFieldDelegate <UITextFieldDelegate>
@optional
-(void)textFieldDidHitBackspaceWithEmptyText:(MyTextField *)textField;
@end
Sam
fonte
2
Para que isso funcione no iOS8 (onde há um erro que nunca chama esse método delegado), consulte esta resposta: stackoverflow.com/a/25862878/893101 . Mais detalhes sobre o bug do ios8: devforums.apple.com/message/1009150#1009150
pIkEL
2

No iOS 6, o método deleteBackward é chamado no UITextField quando o backspace é pressionado, inclusive quando o campo está vazio. Assim, você pode subclassificar UITextField e fornecer sua própria implementação deleteBackward (invocando super's também.)

Ainda estou suportando o iOS 5, portanto, precisarei de uma combinação da resposta de Andrew e isso.

tracy
fonte
1

:) apenas para o título "Detectar backspace", onde eu uso UIKeyboardTypeNumberPad.

Também encontro a mesma pergunta hoje à noite, e a seguir está o meu código para descobrir:

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

Como com UIKeyboardTypeNumberPad, o usuário pode inserir apenas Number ou backspace; portanto, quando o comprimento da string for 0, ele deverá ser a chave de backspace.

Espero que o acima faça alguma ajuda.

Jason Lee
fonte
É o mesmo com qualquer tipo de teclado.
ma11hew28
como conectar este método ao meu campo de texto?
user230910
1

Em vez de tentar pré-construir o que VAI SER no campo de texto ou descobrir qual caractere especial foi inserido no shouldChangeCharactersInRangemétodo, sugiro fazer o seguinte:

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

Isso permite que você chame um método diretamente após a conclusão da operação atual. O que é interessante sobre isso é que, quando terminar, o valor modificado já estará no UITextField. Nesse ponto, você pode apenas verificar seu comprimento e / ou validar com base no que está lá.

Aaron
fonte
1

Subclassificar UITextField não funcionou para mim no iOS 8.3, deleteBackward nunca foi chamado.

Aqui está a solução que usei, funciona em todas as versões do iOS 8 e também em outras versões do 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
fonte
1

No arquivo .h, adicione o delegado 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;
}   

Formatação aprimorada

Anjali Prasad
fonte
1

Eu implementei a solução semelhante com pequenas melhorias que me dirão que, se o campo de texto tiver algum valor enquanto o usuário tocar no backspace. Isso é útil para o meu caso, quando devo focar apenas em outro campo de texto se o campo de texto estiver vazio quando o backspace for pressionado.

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
fonte
1

A resposta mais poplar está faltando uma coisa - a capacidade de detectar se o campo de texto estava vazio ou não.

Ou seja, quando você substitui o método deleteBackwards () de uma subclasse TextField, ainda não sabe se o campo de texto já estava vazio. (Antes e depois de deleteBackwards (), textField.text!é uma sequência vazia:"" )

Aqui está a minha melhoria, com uma verificação do vazio antes da exclusão.

1. Crie um protocolo de delegação que estenda UITextFieldDelegate

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

2. Subclasse 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. Implemente seu novo protocolo de delegação

extension MyViewController: MyTextFieldDelegate {
    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool) {
        if wasEmpty {
            // do what you want here...
        }
    }
}
Tim
fonte
1

Manipulador abrangente para campo de texto com número de um dígito para o Swift 5.1 :

  • Supondo que você tenha uma coleção de saída de textFields (também com delegados conectados)

1 passo

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 Etapa

final class ViewController: UIViewController {

    @IBOutlet private var textFields: [MyTextField]!

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

3 Etapa

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
fonte
0

Aqui minha solução baseada na idéia @andrew:

em algum lugar, por exemplo, em viewDidLoad

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

e depois

    @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
fonte
0

Você pode verificar o texto da visualização / campo de texto para ver se está vazio e garantir que o texto de substituição também esteja vazio no método delegado shouldChangeTextIn.

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if (textView.text == "" && text == "") {
        print("Backspace on empty text field.")
    }
    return true
}
michael-k101
fonte
-2

Algo assim:

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

é claro que o hash é para uma sequência de caracteres.

user1375355
fonte
-2

Usando o método TextField Delegate:

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

Adicione o seguinte código no método acima para detectar o evento de exclusão

if(textField == YourTextField)
{
    if ([string length] == 0 && range.length > 0)
    {
        // Your Code after deletion of character
    }
}
kalim sayyad
fonte
-3

Para simplificar, aqui está a única condição que você precisa verificar

     if (range.length==1)
Bhumit Mehta
fonte
-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
fonte
2
Talvez uma pequena explicação de onde colocar isso?
Alex Cio
-4

Em UITextViewDelegate:

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

funciona bem para mim.

atualização para pinyin simplificado chinês e entrada de caligrafia chinesa:

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

base no documento diz:

"Se o usuário pressionar o deleteKey, o comprimento do intervalo será 1 e um objeto de string vazio substituirá esse caractere único."

palhaço
fonte
1
Esta questão é sobre UITextField, não UITextView.
ma11hew28