Rileva backspace in UITextField vuoto


126

Esiste un modo per rilevare quando si preme il tasto Backspace/ Deletenella tastiera dell'iPhone su un dispositivo UITextFieldvuoto? Voglio sapere quando Backspaceviene premuto solo se UITextFieldè vuoto.


Sulla base del suggerimento di @Alex Reynolds in un commento, ho aggiunto il seguente codice durante la creazione del mio campo di testo:

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

Questa notifica viene ricevuta (la handleTextFieldChangedfunzione viene chiamata), ma non ancora quando premo il Backspacetasto in un campo vuoto. Qualche idea?


Sembra esserci un po 'di confusione su questa domanda. Voglio ricevere una notifica quando Backspaceviene premuto il tasto. Questo è tutto. Ma la soluzione deve funzionare anche quando UITextFieldè già vuota.


Penso che potresti voler dire "solo se UITextField è vuoto" anziché "solo se la tastiera è vuota" ...?
Steve Harrison,

@Steve Harrison: grazie. Aggiornato quello.
marcc

Sto cercando di fare qualcosa di simile, quale soluzione hai preso allora? Quello che sto facendo è un campo di testo in una vista di scorrimento, quando scrivo del testo, i suggerimenti vengono visualizzati e quando faccio clic su uno, un oggetto etichetta viene posizionato a sinistra del campo di testo. Grazie in anticipo: D
Pasta

Soluzione 2011/11 per UITextField vuota usando l'inganno runtime: bjhomer.blogspot.com/2011/11/…
Jano

4
Ridicolmente brama qualcosa di così banale. Questo non dovrebbe essere difficile.
Adam Waite,

Risposte:


36

Potrebbe essere un tiro lungo ma potrebbe funzionare. Prova a impostare il testo del campo di testo su un carattere spazio di larghezza zero \u200B. Quando il backspace viene premuto su un campo di testo che appare vuoto, in realtà cancellerà il tuo spazio. Quindi puoi semplicemente reinserire lo spazio.

Potrebbe non funzionare se l'utente riesce a spostare il cursore a sinistra dello spazio.


3
@Andrew, questo è l'approccio che ho deciso di adottare. Ci è voluto un po 'di codice, ma è sicuramente efficace. Grazie per l'aiuto invece di provare a dirmi che sto facendo qualcosa di sbagliato.
marzo

2
Questa tecnica può funzionare su iPhone> 3.1.3, ma è confusa e potrebbe rompersi su versioni future, ecc. Penso di aver trovato una soluzione più pulita e stabile per come rilevare la pressione di un tasto della tastiera su iPhone / iOS .
ma11hew28,

6
Posso confermare che l'eliminazione non viene rilevata se l'utente riesce a spostare il cursore a sinistra dello spazio. Se si riesce a capire come risolvere il problema, allora si dovrebbe anche sottoclasse UITextFielde mettere in atto canPerformAction:withSender:per return NOper select:e selectAll:azioni quando il testo è uguale alla stringa @"\u200B".
ma11hew28,

2
Il problema è che questo non funziona per i campi di test sicuri. Qualche idea su come gestirlo?
Kyle Clegg,

7
Scusa, ma questa idea è cattiva. È incredibile hacky e non dovrebbe essere la risposta accettata con circa 30 voti. Vorrei sottoclasse invece UITextField, come alcuni altri commentatori hanno menzionato.
Brian Sachetta,

155

Swift 4:


Sottoclasse UITextField:

// MyTextField.swift
import UIKit

protocol MyTextFieldDelegate: AnyObject {
    func textFieldDidDelete()
}

class MyTextField: UITextField {

    weak var myDelegate: MyTextFieldDelegate?

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

}

Implementazione:

// 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:


Sottoclasse 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

Ora aggiungi semplicemente MyTextFieldDelegate al tuo UIViewControllere imposta UITextFields myDelegate su 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
Questa è la soluzione migliore La risposta accettata è un hack. L'obiettivo C si basa sul sottoclasse e questa soluzione lo utilizza correttamente per risolvere il problema.
TJ,

Cosa accadrà ai miei metodi delegati esistenti in ViewController classe se imposto il delegato del mio campo di testo su una sottoclasse UITextFieldanziché suUIViewController
rohan-patel,

4
A quanto pare questo non funziona in iOS 8 in questo momento, a causa di quello che sembra un bug di Apple: devforums.apple.com/message/1045312#1045312
chug2k

1
Ho usato una soluzione alternativa per bug ios8 come nella mia risposta e ha funzionato. Potrebbe essere utile per coloro che sono alla ricerca di una soluzione.
furkan3ayraktar,

1
deleteBackward()non verrà chiamato se si è return falseintextField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
igrrik il

41

Aggiornamento: vedi la risposta di JacobCaraballo per un esempio che ha la precedenza -[UITextField deleteBackward].

Dai un'occhiata UITextInput, UIKeyInputha in particolare un deleteBackwardmetodo delegato che viene sempre chiamato quando viene premuto il tasto Canc. Se stai facendo qualcosa di semplice, potresti considerare solo la sottoclasse UILabele renderlo conforme al UIKeyInputprotocollo, come fatto da SimpleTextInput e da questo esempio di UIKeyInput di iPhone . Nota: UITextInpute i suoi parenti (incluso UIKeyInput) sono disponibili solo in iOS 3.2 e versioni successive.


2
Questa è la risposta esatta. È non complicato e molto semplice con una rapida sottoclasse di UITextField.
Sam

Ho appena visto la risposta di Jacob qui sotto. Dà un esempio dettagliato di questo.
Sam,

Vale la pena notare che questa risposta non funziona in iOS 5. Se il campo di testo è vuoto, premendo backspace non si richiama questo metodo.
jfeldman,

31

Codice come il seguente:

@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

Alla fine, dimentica di cambiare la proprietà Classe personalizzata del campo di testo in "MyTextField"


5
Questa dovrebbe essere la risposta accettata. Pulito e in realtà risponde alla domanda.
Ryan Romanchuk,

1
Risponde alla domanda ... Fintanto che ti rivolgi a iOS 6.0+. Sfortunatamente, su iOS 5, deleteBackward non è mai stato chiamato nella tua sottoclasse.
BJ Homer,

2
BJ Homer, il 93% dei dispositivi è su iOS 6, quindi non prendere di mira iOS 5 in genere non è un grosso problema.
Jonathan.

2
Sono contento di aver continuato a scorrere abbastanza in basso per trovare questo. 100% il modo giusto per farlo oggi in IOS 7.
MusiGenesis

Ho visto tante altre risposte a questa domanda che sono solo soluzioni alternative e quasi nessuna di esse affronta la situazione in cui il tasto backspace viene premuto in un campo vuoto. Questo, tuttavia, è perfetto e un modo davvero pulito per farlo.
Christopher Hannah,

19

Implementazione rapida:

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

Grazie, posso sapere che questo metodo è consigliato da Apple o è hack. sembra non documentato per il campo di testo.
Kalpesh Jetani,

Ha funzionato per me con un textView. grazie per la condivisione;)
Edouard Barbier,

Ha funzionato per me quando il campo di testo è vuoto e si fa clic sullo spazio posteriore.
Ramakrishna,

17

Ho trovato un modo più semplice della subclasssoluzione. Anche è un po 'strano ma funziona bene.

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

È un po 'strano perché il risultato del confronto è -8. Forse mi sbaglierò in qualche punto di C Programming. Ma è il lavoro giusto;)


1
Backstroke non è impostato '\ b'. Ma se esegui il debug con attenzione, vedrai '\ 0'. Quindi ottengo il risultato 0 che è due valori uguali nel metodo strcmp. const char * stoke = [text cStringUsingEncoding: NSASCIIStringEncoding]; const char * backstroke = "\ 0"; // questo è uguale a \ b -> "\ x08"; strcmp (backstroke, stoke);
Yoon Lee,

Inoltre, secondo la definizione di strcmp (s1, s2), restituisce 0 se s1 == s2,> 0 s1 è lessicograficamente maggiore di s2 viceversa.
Yoon Lee,

Non capisco come possa funzionare? @YoonLee: non stai dicendo strcmpneanche i ritorni -1, 0, or 1? Questa era la mia comprensione.
Chug2k,

1
in textview rilevi sempre il backspace anche se non c'è testo, UITextField è diverso
LolaRun,

2
Questo è un UITextViewDelegatemetodo, no UITextFieldDelegate.
pkamb,

11

Prova il delegate

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

Quindi controlla se il range.length == 1che sembra essere il caso quando backspaceviene colpito.


8
Chiamato solo quando il campo non è vuoto, però. Nota la domanda originale. :)
Eric Goldberg,

Usa UITextView per questo.
Oleg,

11

si prega di utilizzare sotto il codice che ti aiuterà a rilevare il tasto di cancellazione della tastiera anche se il campo di testo è vuoto.

Obiettivo C:

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

Veloce:

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

Tx - proprio quello di cui avevo bisogno. Ma dove è documentato ??
Andy Weinstein,

9

La risposta di Niklas Alvaeus mi ha aiutato con un problema simile

Stavo limitando l'ingresso a un set di caratteri specifico, ma ignoravo i backspaces. Quindi l'ho fatto controllare range.length == 1prima di tagliare il file NSString. Se è vero, restituisco semplicemente la stringa e non la taglio. Vedi sotto

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

Il metodo prevede un valore booleano e non una stringa come valore di ritorno
Pascalius,

4

Per quelli che hanno problemi con la risposta di Jacob ho implementato la mia sottoclasse del campo di testo come segue e funziona alla grande!

#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

puoi scrivere il codice per swift. Ho ricevuto un errore "Conferma ridondante su protoco uikeyinput"
Raj Aggrawal,

4

Sì, usa il metodo seguente per rilevare backspace, quando textField è vuoto.

È necessario aggiungere UITextFieldDelegate

yourTextField.delegate = self (DEVE RICHIESTO)

Swift:

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

Obiettivo C:

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

5
Questo non mi chiama nemmeno per me. Tutti gli altri metodi delegati vengono chiamati come e quando si verifica un evento.
Hemang,

Grazie amico .. L'hai inchiodato :)
MS.

@ McDonal_11 Penso che ti sei dimenticato di impostare textfield.delegate = self of textfield.
Himanshu padia,

Ho impostato. altri metodi delegati di UITextField funzionano bene. Questo da solo non funziona. Cosa mi manca ??
McDonal_11

3

L'uso migliore che ho trovato per rilevare backspace è rilevare quando l'utente ha premuto backspace in uno spazio vuoto UITextField. Ad esempio, se hai appannato i destinatari nell'app di posta, quando premi backspace inUITextField , seleziona l'ultimo destinatario "gorgogliante".

Questo può essere fatto in modo simile alla risposta di Jacob Caraballo. Ma nella risposta di Jacob, se UITextFieldè rimasto un carattere quando si colpisce backspace, al momento della ricezione del messaggio delegato, UITextFieldsarà già vuoto, quindi si sta effettivamente rilevando backspacesu un campo di testo con al massimo un carattere.

In realtà, se si desidera rilevare backspaceun UITextFieldcon esattamente zero caratteri (vuoto), è necessario inviare il messaggio a delegateprima della chiamata a super deleteBackward. Per esempio:

#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

L'interfaccia per un tale campo di testo sarebbe simile a questa:

@protocol MyTextFieldDelegate;

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

@protocol MyTextFieldDelegate <UITextFieldDelegate>
@optional
-(void)textFieldDidHitBackspaceWithEmptyText:(MyTextField *)textField;
@end

2
Affinché ciò funzioni in iOS8 (dove c'è un bug che non chiama mai questo metodo delegato), vedi questa risposta: stackoverflow.com/a/25862878/893101 . Maggiori dettagli sul bug ios8: devforums.apple.com/message/1009150#1009150
pIkEL

2

In iOS 6, il metodo deleteBackward viene chiamato su UITextField quando viene premuto backspace, anche quando il campo è vuoto. Quindi puoi sottoclassare UITextField e fornire la tua implementazione deleteBackward (invocando anche i super.)

Sto ancora supportando iOS 5, quindi avrò bisogno di una combinazione della risposta di Andrew e questa.


1

:) solo per il titolo "Rileva backspace", dove uso UIKeyboardTypeNumberPad.

Stasera incontro anche la stessa domanda e il seguente codice è per scoprirlo:

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

Perché con UIKeyboardTypeNumberPad, l'utente può solo inserire Numero o backspace, quindi quando la lunghezza della stringa è 0, deve essere una chiave backspace.

Spero che quanto sopra possa aiutare.


È lo stesso con qualsiasi tipo di tastiera.
ma11hew28,

come posso collegare questo metodo al mio campo di testo?
user230910

1

Invece di provare a precostruire ciò che SARÀ nel campo di testo o capire quale carattere speciale è stato inserito nel shouldChangeCharactersInRangemetodo, suggerirei di fare quanto segue:

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

Ciò consente di chiamare un metodo direttamente dopo il completamento dell'operazione corrente. La cosa interessante di questo è che, al termine, il valore modificato sarà già in UITextField. A quel punto, puoi semplicemente controllarne la lunghezza e / o confermare in base a cosa c'è.


1

La sottoclasse di UITextField non ha funzionato per me su iOS 8.3, deleteBackward non è mai stato chiamato.

Ecco la soluzione che ho usato, funziona su tutte le versioni di iOS 8 e dovrebbe funzionare anche su altre versioni di 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
}

1

Nel file .h aggiungi il delegato 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;
}   

formattazione migliorata


1

Ho implementato la soluzione simile con piccoli miglioramenti che mi diranno che se il campo di testo ha qualche valore mentre l'utente ha toccato il backspace. Questo è utile per il mio caso quando dovrei concentrarmi su un altro campo di testo se il campo di testo è vuoto quando viene premuto backspace.

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

1

La risposta alla maggior parte dei pioppi manca di una cosa: la capacità di rilevare se il campo di testo era vuoto o meno.

Cioè, quando si sovrascrive il metodo deleteBackwards () di una sottoclasse TextField, non si sa ancora se il campo di testo era già vuoto. (Sia prima che dopo deleteBackwards (), textField.text!è una stringa vuota:"" )

Ecco il mio miglioramento, con un controllo del vuoto prima della cancellazione.

1. Creare un protocollo delegato che estende UITextFieldDelegate

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

2. Sottoclasse 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. Implementa il tuo nuovo protocollo delegato

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

1

Gestore completo per il campo di testo con numero a una cifra per Swift 5.1 :

  • Supponendo di disporre di una raccolta di outlet di campi di testo (anche con delegati connessi)

1 passaggio

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 passaggi

final class ViewController: UIViewController {

    @IBOutlet private var textFields: [MyTextField]!

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

3 passaggi

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

0

Ecco la mia soluzione basata sull'idea di @andrew:

da qualche parte, ad esempio in viewDidLoad

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

e poi

    @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 
        }

0

Puoi controllare il testo della vista / campo del testo per vedere se è vuoto e assicurarti che anche il testo sostitutivo sia vuoto nel metodo delegato shouldChangeTextIn.

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

-2

Qualcosa come questo:

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

ovviamente l'hash è per una stringa di caratteri.


-2

Utilizzando il metodo Delegato TextField:

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

Aggiungi il seguente codice nel metodo sopra per rilevare l'evento di eliminazione

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

-3

Per mantenerlo semplice qui è l'unica condizione che devi controllare

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

2
Forse una piccola spiegazione dove metterlo?
Alex Cio,

-4

In UITextViewDelegate:

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

funziona bene per me.

aggiornamento per pinyin cinese semplificato e input per la scrittura cinese:

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

base sul documento dice:

"Se l'utente preme il tasto deleteKey, la lunghezza dell'intervallo è 1 e un oggetto stringa vuoto sostituisce quel singolo carattere."


1
Questa domanda riguarda UITextFieldno UITextView.
ma11hew28,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.