Detectar retroceso en UITextField vacío

126

¿Hay alguna forma de detectar cuando se presiona la tecla Backspace/ Deleteen el teclado del iPhone en un dispositivo UITextFieldque está vacío? Quiero saber cuándo Backspacese presiona solo si UITextFieldestá vacío.


Según la sugerencia de @Alex Reynolds en un comentario, agregué el siguiente código al crear mi campo de texto:

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

Esta notificación se recibe ( handleTextFieldChangedse llama a la función), pero aún no cuando presiono la Backspacetecla en un campo vacío. ¿Algunas ideas?


Parece haber cierta confusión en torno a esta pregunta. Quiero recibir una notificación cuando Backspacese presiona la tecla. Eso es. Pero la solución también debe funcionar cuando UITextFieldya está vacío.

marcc
fuente
Creo que puede querer decir "solo si el UITextField está vacío" en lugar de "solo si el teclado está vacío" ...?
Steve Harrison, el
@ Steve Harrison: gracias. Actualizado eso.
marcc
Estoy tratando de hacer algo similar, ¿qué solución obtuviste entonces? Lo que estoy haciendo es un campo de texto en una vista de desplazamiento, cuando escribo algo de texto, se muestran sugerencias y cuando hago clic en uno, se coloca un objeto de etiqueta a la izquierda del campo de texto. Gracias de antemano: D
Dough
Solución 2011/11 para UITextField vacío utilizando trucos de tiempo de ejecución: bjhomer.blogspot.com/2011/11/…
Jano
44
Ridículamente anhelo de algo tan trivial. Esto no debería ser difícil.
Adam Waite

Respuestas:

36

Esto puede ser una posibilidad remota, pero podría funcionar. Intente establecer el texto del campo de texto en un carácter de espacio de ancho cero \u200B. Cuando se presiona la tecla de retroceso en un campo de texto que aparece vacío, en realidad eliminará su espacio. Entonces puedes reinsertar el espacio.

Puede no funcionar si el usuario logra mover el cursor a la izquierda del espacio.

Andrés
fuente
3
@ Andrew, este es el enfoque que decidí tomar. Tomó un poco de código, pero ciertamente es efectivo. Gracias por la ayuda en lugar de tratar de decirme que estoy haciendo algo mal.
marcc
2
Esta técnica puede funcionar en iPhone> 3.1.3, pero es hacky y puede romperse en futuras versiones, etc. Creo que encontré una solución más limpia y estable para detectar una pulsación de tecla de borrar en el iPhone / iOS .
ma11hew28
66
Puedo confirmar que no se detecta la eliminación si el usuario logra mover el cursor a la izquierda del espacio. Si usted puede encontrar la manera de arreglar eso, entonces también debe subclase UITextFieldy aplicar canPerformAction:withSender:a return NOpara select:y selectAll:acciones cuando el texto es igual a la cadena @"\u200B".
ma11hew28
2
El problema es que esto no funciona para campos de prueba seguros. ¿Alguna idea de cómo manejar eso?
Kyle Clegg
77
Lo siento, pero esta idea es mala. Es increíblemente hacky y no debería ser la respuesta aceptada con más de 30 votos a favor. Subclase UITextField en su lugar, como algunos de los otros comentaristas han mencionado.
Brian Sachetta
155

Swift 4:


Subclase UITextField:

// MyTextField.swift
import UIKit

protocol MyTextFieldDelegate: AnyObject {
    func textFieldDidDelete()
}

class MyTextField: UITextField {

    weak var myDelegate: MyTextFieldDelegate?

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

}

Implementación:

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

}

C objetivo:


Subclase 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

Ahora simplemente agregue MyTextFieldDelegate a su UIViewControllery configure su UITextFields myDelegate en 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
fuente
9
Esta es la mejor solución. La respuesta aceptada es un truco. El objetivo C se basa en subclases y esta solución lo utiliza correctamente para resolver el problema.
TJ
¿Qué pasará con mis métodos de delegado existentes en ViewController clase si configuro el delegado de mi campo de texto en una subclase de en UITextFieldlugar de?UIViewController
rohan-patel
44
Aparentemente, esto no funciona en ios8 en este momento, debido a lo que parece un error de Apple: devforums.apple.com/message/1045312#1045312
chug2k
1
Utilicé una solución alternativa para el error ios8 como en mi respuesta y funcionó. Puede ser útil para quienes buscan una solución.
furkan3ayraktar
1
deleteBackward()no se llamará si return falseentextField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
igrrik
41

Actualización: Vea la respuesta de JacobCaraballo para un ejemplo que anula -[UITextField deleteBackward].

Echa un vistazo UITextInput, específicamenteUIKeyInput tiene un deleteBackwardmétodo de delegado que siempre se llama cuando se presiona la tecla Eliminar. Si está haciendo algo simple, entonces podría considerar simplemente subclasificar UILabely hacer que se ajuste al UIKeyInputprotocolo, como lo hace SimpleTextInput y este ejemplo de iPhone UIKeyInput . Nota: UITextInputy sus parientes (incluidos UIKeyInput) solo están disponibles en iOS 3.2 y versiones posteriores.

ma11hew28
fuente
2
Esta es la respuesta correcta. No es hacky y es muy simple con una subclase rápida de UITextField.
Sam
Acabo de ver la respuesta de Jacob a continuación. Da un ejemplo detallado de esto.
Sam
Vale la pena señalar que esta respuesta no funciona en iOS 5. Si el campo de texto está vacío, presionar la tecla de retroceso no invoca este método.
jfeldman
31

Código como el siguiente:

@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 último, olvide cambiar la propiedad de Clase personalizada del campo de texto a "MyTextField"

Jeffrey Loo
fuente
55
Esta debería ser la respuesta aceptada. Limpio, y en realidad responde a la pregunta.
Ryan Romanchuk
1
Responde la pregunta ... siempre y cuando esté apuntando a iOS 6.0+. Lamentablemente, en iOS 5, deleteBackward simplemente nunca fue llamado en su subclase.
BJ Homer
2
BJ Homer, el 93% de los dispositivos están en iOS 6, por lo que no apuntar a iOS 5 generalmente no es tan importante.
Jonathan.
2
Me alegro de haber seguido desplazándome lo suficiente como para encontrar esto. 100% la forma correcta de hacer esto hoy en iOS 7.
MusiGenesis
He visto tantas otras respuestas para esta pregunta que son solo soluciones alternativas, y casi ninguna de ellas trata la situación en la que la tecla de retroceso se presiona en un campo vacío. Sin embargo, esto es perfecto y una forma realmente limpia de hacerlo.
Christopher Hannah
19

Implementación 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
fuente
Gracias, ¿puedo saber que Apple recomienda este método? parece indocumentado para el campo de texto.
kalpesh jetani
Me funcionó con un textView. gracias por compartir;)
Edouard Barbier
Me funcionó cuando el campo de texto está vacío y se hace clic en el espacio posterior.
Ramakrishna
17

He encontrado otra manera más fácil que la subclasssolución. Incluso es un poco extraño, pero funciona bien.

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

Es un poco extraño porque el resultado de la comparación es -8. Tal vez me equivoque en algún punto de C Programming. Pero es el trabajo correcto;)

Jerapong Nampetch
fuente
1
Retroceso no está configurado '\ b'. Pero si depura cuidadosamente, verá '\ 0'. Entonces obtengo el resultado 0 que es que dos valores son iguales en el método strcmp. const char * stoke = [texto cStringUsingEncoding: NSASCIIStringEncoding]; const char * backstroke = "\ 0"; // esto es igual a \ b -> "\ x08"; strcmp (golpe de espalda, stoke);
Yoon Lee
Además, según la definición de strcmp (s1, s2), devuelve 0 si s1 == s2,> 0 s1 es lexicográficamente mayor que s2 y viceversa.
Yoon Lee
No entiendo cómo podría funcionar esto. @YoonLee: ¿no estás diciendo strcmpdevoluciones tampoco -1, 0, or 1? Ese fue mi entendimiento.
chug2k
1
en la vista de texto siempre se detecta el retroceso, incluso si no hay texto, el UITextField es diferente
LolaRun
2
Este es un UITextViewDelegatemétodo, no UITextFieldDelegate.
pkamb
11

Prueba el delegate

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

Luego, compruebe si range.length == 1parece ser el caso cuando backspacese golpea.

Niklas Alvaeus
fuente
8
Sin embargo, solo se llama cuando el campo no está vacío. Tenga en cuenta la pregunta original. :)
Eric Goldberg
Use UITextView para esto.
Oleg
11

utilice el siguiente código, lo ayudará a detectar la tecla de eliminación del teclado incluso si el campo de texto está vacío.

C objetivo :

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

Rápido:

func keyboardInputShouldDelete(_ textField: UITextField) -> Bool { return true }
Pritesh
fuente
Tx: justo lo que necesitaba. ¿Pero dónde está documentado?
Andy Weinstein
9

La respuesta de Niklas Alvaeus me ayudó con un problema similar

Estaba limitando la entrada a un conjunto de caracteres específico, pero ignoraba los espacios de retroceso. Así que lo revisé range.length == 1antes de recortarlo NSString. Si es cierto, solo devuelvo la cadena y no la recorto. Vea abajo

 - (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
fuente
El método espera un valor booleano y no una cadena como valor de retorno
Pascalius
4

Para los que tienen problemas con la respuesta de Jacob, implementé mi subclase de campo de texto de la siguiente manera y funciona muy bien.

#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
fuente
¿Puedes escribir el código para swift? Recibí un error "confirmación redundante para protoco uikeyinput"
Raj Aggrawal
4

Sí, utilice el siguiente método para detectar retroceso, cuando textField esté vacío.

Necesita agregar UITextFieldDelegate

yourTextField.delegate = self (DEBE REQUERIRSE)

Rápido:

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

C objetivo:

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField { 
    return YES; 
}
Himanshu padia
fuente
55
Esto ni siquiera me llama. Todos los demás métodos de delegado se llaman cuando ocurre un evento.
Hemang
Gracias amigo ... Lo has clavado. :)
MS.
@ McDonal_11 Creo que olvidó configurar textfield.delegate = self of textfield.
Himanshu padia
He puesto. otros métodos delegados de UITextField están funcionando bien. Este solo no funciona. ¿Qué extraño?
McDonal_11
3

El mejor uso que he encontrado para detectar el retroceso es detectar cuándo el usuario ha presionado el retroceso en un espacio vacío UITextField. Por ejemplo, si ha "burbujeado" destinatarios en la aplicación de correo, cuando presiona la tecla de retroceso en elUITextField , selecciona el último destinatario 'burbujeado'.

Esto se puede hacer de manera similar a la respuesta de Jacob Caraballo. Pero en la respuesta de Jacob, si UITextFieldle queda un carácter al presionar la tecla de retroceso, para cuando se reciba el mensaje del delegado, el mensaje UITextFieldya estará vacío, por lo que está detectando efectivamentebackspace en un campo de texto con un máximo de caracteres.

En realidad, si desea detectar backspaceen un UITextFieldcon exactamente cero caracteres (vacío), debe enviar el mensaje delegateantes de la llamada super deleteBackward. Por ejemplo:

#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

La interfaz para dicho campo de texto se vería así:

@protocol MyTextFieldDelegate;

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

@protocol MyTextFieldDelegate <UITextFieldDelegate>
@optional
-(void)textFieldDidHitBackspaceWithEmptyText:(MyTextField *)textField;
@end
Sam
fuente
2
Para que esto funcione en iOS8 (donde hay un error que hace que nunca se llame a este método de delegado), consulte esta respuesta: stackoverflow.com/a/25862878/893101 . Más detalles sobre el error ios8: devforums.apple.com/message/1009150#1009150
pIkEL
2

En iOS 6, el método deleteBackward se llama en UITextField cuando se presiona la tecla de retroceso, incluso cuando el campo está vacío. Por lo tanto, puede subclasificar UITextField y proporcionar su propia implementación deleteBackward (invocando super's también).

Sin embargo, todavía soporto iOS 5, así que necesitaré una combinación de la respuesta de Andrew y esto.

tracy
fuente
1

:) solo por el título "Detectar retroceso", donde uso UIKeyboardTypeNumberPad .

También me encuentro con la misma pregunta esta noche, y el siguiente es mi código para averiguarlo:

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

Porque con UIKeyboardTypeNumberPad , el usuario solo puede ingresar Número o retroceso, por lo que cuando la longitud de la cadena es 0, debe ser la tecla de retroceso.

Espero que lo anterior ayude un poco.

Jason Lee
fuente
Es lo mismo con cualquier tipo de teclado.
ma11hew28
¿Cómo conecto este método a mi campo de texto?
user230910
1

En lugar de intentar preconstruir lo que SERÁ en el campo de texto o averiguar qué carácter especial se ha ingresado en el shouldChangeCharactersInRangemétodo, sugeriría hacer lo siguiente:

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

Esto le permite llamar a un método directamente después de que se complete la operación actual. Lo bueno de esto es que, para cuando se complete, el valor modificado ya estará en UITextField. En ese punto, puede verificar su longitud y / o validar en función de lo que hay allí.

Aaron
fuente
1

Subclasificar UITextField no funcionó para mí en iOS 8.3, nunca se llamó a deleteBackward.

Aquí está la solución que utilicé, funciona en todas las versiones de iOS 8 y debería funcionar también en otras versiones de 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
fuente
1

En el archivo .h, agregue el 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;
}   

Formato mejorado

Anjali Prasad
fuente
1

He implementado una solución similar con mejoras menores que me dirán que si el campo de texto tiene algún valor mientras el usuario ha pulsado el espacio de retroceso. Esto es útil para mi caso cuando solo debería centrarme en otro campo de texto si el campo de texto está vacío cuando se presiona la tecla de retroceso.

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

A la respuesta más popular le falta una cosa: la capacidad de detectar si el campo de texto estaba vacío o no.

Es decir, cuando anula el método deleteBackwards () de una subclase TextField, aún no sabe si el campo de texto ya estaba vacío. (Tanto antes como después de deleteBackwards (), textField.text!es una cadena vacía:"" )

Aquí está mi mejora, con un control de vacío antes de la eliminación.

1. Cree un protocolo delegado que extienda UITextFieldDelegate

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

2. Subclase 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 su nuevo protocolo de delegado

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

Controlador completo para el campo de texto con un número de un solo dígito para Swift 5.1 :

  • Suponiendo que tiene una colección de salida de textFields (también con delegados conectados)

1 paso

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 pasos

final class ViewController: UIViewController {

    @IBOutlet private var textFields: [MyTextField]!

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

Paso 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
fuente
0

Aquí mi solución basada en la idea de @andrew:

en algún lugar, por ejemplo en viewDidLoad

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

y entonces

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

Puede verificar el texto de la vista / campo de texto para ver si está vacío y asegurarse de que el texto de reemplazo también esté vacío en el método de 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
fuente
-2

Algo como esto:

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

Por supuesto, el hash es para una cadena de caracteres.

usuario1375355
fuente
-2

Usando el método Delegado TextField:

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

Agregue el siguiente código en el método anterior para detectar el evento de eliminación

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

Para mantenerlo simple, esta es la única condición que debe verificar

     if (range.length==1)
Bhumit Mehta
fuente
-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
fuente
2
Tal vez una pequeña explicación donde poner esto?
Alex Cio
-4

En UITextViewDelegate:

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

funciona bien para mi

actualización para pinyin chino simplificado y entrada de escritura china:

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

base en el documento dice:

"Si el usuario presiona deleteKey, la longitud del rango es 1 y un objeto de cadena vacío reemplaza ese carácter individual".

bufón
fuente
1
Esta pregunta es sobre UITextField, no UITextView.
ma11hew28