2015-04-08 22 views
14

Sono alla ricerca di soluzioni su come acquisire un evento backspace, la maggior parte delle risposte di Overflow dello stack sono in Objective-C ma ho bisogno del linguaggio Swift.Rileva backspace Evento in UITextField

Prima ho impostato delegato per l'UITextField e impostarlo su auto

self.textField.delegate = self; 

allora so usare shouldChangeCharactersInRange metodo delegato per rilevare se un backspace è stato premuto è tutto il codice è in Objective-C. Ho bisogno in Swift del seguente metodo, come di seguito viene utilizzato.

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 
    const char * _char = [string cStringUsingEncoding:NSUTF8StringEncoding]; 
    int isBackSpace = strcmp(_char, "\b"); 

    if (isBackSpace == -8) { 
     // NSLog(@"Backspace was pressed"); 
    } 

    return YES; 
} 
+2

E come si presenta il tuo approccio a questo problema con Swift? Per favore. Mostraci il tuo impegno e lascia che ti aiutiamo dove hai sbagliato. Stack Overflow non è un servizio di scrittura del codice. – nhgrif

+0

Sto anche cercando questa soluzione. Se qualcuno lo sa, per favore, rispondi. –

risposta

32

Speranza vi aiuterà: p

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 
    let char = string.cStringUsingEncoding(NSUTF8StringEncoding)! 
    let isBackSpace = strcmp(char, "\\b") 

    if (isBackSpace == -92) { 
     println("Backspace was pressed") 
    } 
    return true 
} 
+0

Questo metodo delegato non viene attivato. Il delegato è configurato nel metodo 'viewDidLoad()'. –

+6

questo funziona benissimo a meno che textField non sia vuoto – gbk

+2

-1: questo codice funziona, ma per caso. [La documentazione] (https://developer.apple.com/documentation/uikit/uitextfielddelegate/1619599-textfield) specifica che 'stringa' sarà una stringa vuota se l'utente cancella uno o più caratteri. – ravron

6

Prova questa

public func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 

if(string == "") { 

     print("Backspace pressed"); 
     return true; 
    } 
} 

Nota: È possibile tornare "vero" se si desidera consentire backspace. Altrimenti è possibile restituire "false".

+1

Cosa succede se il testo corrente è vuoto? –

+0

Questo delegato non si chiamerà –

+3

'string ==" "meglio usare' .isEmpty' – gbk

8

Se è necessario rilevare il backspace anche in campo di testo vuoto (ad esempio, se è necessario passare automaticamente al campo di testo precedente su backSpace premendo), è possibile utilizzare la combinazione dei metodi proposti - aggiungere il segno invisibile e utilizzare il metodo di delega standard textField:shouldChangeCharactersInRange:replacementString: seguono

  1. Creare segno invisibile

    private struct Constants { 
        static let InvisibleSign = "\u{200B}" 
    } 
    
  2. Set delegato per textField

    textField.delegate = self 
    
  3. Su evento EditingChanged testo di controllo e, se necessario, aggiungere il simbolo invisibile come segue:

    @IBAction func didChangeEditingInTextField(sender: UITextField) { 
        if var text = sender.text { 
         if text.characters.count == 1 && text != Constants.InvisibleSign { 
          text = Constants.InvisibleSign.stringByAppendingString(text) 
          sender.text = text 
         } 
        } 
    } 
    

enter image description here

  1. Aggiungi realizzazione del metodo delegato textField:shouldChangeCharactersInRange:replacementString:

    extension UIViewController : UITextFieldDelegate { 
        // MARK: - UITextFieldDelegate 
        func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 
    
         let char = string.cStringUsingEncoding(NSUTF8StringEncoding)! 
         let isBackSpace = strcmp(char, "\\b") 
    
         if (isBackSpace == -92) { 
          if var string = textField.text { 
           string = string.stringByReplacingOccurrencesOfString(Constants.InvisibleSign, withString: "") 
           if string.characters.count == 1 { 
            //last visible character, if needed u can skip replacement and detect once even in empty text field 
            //for example u can switch to prev textField 
            //do stuff here        
           } 
          } 
         } 
         return true 
        } 
    } 
    
13

In Swift 3

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 
    let char = string.cString(using: String.Encoding.utf8)! 
    let isBackSpace = strcmp(char, "\\b") 

    if (isBackSpace == -92) { 
     print("Backspace was pressed") 
    } 
    return true 
} 

:)

1

Swift 4: Se l'utente preme il tasto cancella, stringa è vuota, quindi questo approccio forze textField per accettare solo caratteri da un determinato set di caratteri (in questo caso utf8 caratteri) e backspaces (string.isEmpty case).

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 
    if string.cString(using: String.Encoding.utf8) != nil { 
     return true 
    } else if string.isEmpty { 
     return true 
    } else { 
     return false 
    } 
} 
0

Swift Code 3 e> quindi

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

    return true 
} 
0

preferisco sottoclassi UITextField e prioritario deleteBackward() perché questo è molto più affidabile l'hack di utilizzare shouldChangeCharactersInRange:

class MyTextField: UITextField { 
    override public func deleteBackward() { 
     if text == "" { 
      // do something when backspace is tapped/entered in an empty text field 
     } 
     // do something for every backspace 
     super.deleteBackward() 
    } 
} 

Il shouldChangeCharactersInRange mod combinato con un personaggio invisibile inserito nel campo di testo presenta diversi svantaggi:

  • con una tastiera collegata, si può posizionare il cursore prima del carattere invisibile e il backspace non viene rilevato più,
  • l'utente può anche selezionare quel carattere invisibile (utilizzando Shift Arrow su una tastiera o toccando sulla accento circonflesso) e sarà confuso su quel personaggio strano,
  • la barra di completamento automatico offre scelte strane finché c'è solo questo personaggio invisibile,
  • il placeholder non è mostrata più,
  • viene visualizzato il pulsante chiaro anche quando lo fai no per clearButtonMode = .whileEditing.

Ovviamente, l'annullamento di deleteBackward() è un po 'scomodo a causa della necessità di sottoclasse. Ma la migliore UX ne vale la pena!

E se la sottoclasse è un no-go, ad es. quando si utilizza UISearchBar con il suo UITextField incorporato, il metodo di swizzling dovrebbe andare bene, anche.