2013-05-27 5 views
13

Wenn Sie in iOS 6 Text in ein sicheres Textfeld eingeben, wechseln Sie in ein anderes Textfeld, kehren Sie dann zum sicheren Textfeld zurück und drücken Sie die Rücktaste, um alle Zeichen zu entfernen. Es geht mir gut, aber ich versuche eine Schaltfläche zu aktivieren/deaktivieren, basierend darauf, ob dieses sichere Textfeld Zeichen enthält oder nicht. Ich weiß, wie man bestimmt, welche Zeichen in den Feldern sind und ob eine Rücktaste getroffen wird, aber ich habe Probleme zu bestimmen, wie man erkennt, ob das Löschen aller Charaktere geschieht.iOS 6 UITextField Secure - Wie erkennt man das Zurücksetzen aller Zeichen?

Dies ist die Delegate-Methode, die ich verwende, um den neuen Text eines Feldes zu erhalten, aber ich kann nicht herausfinden, wie der neue Text zu erhalten ist (vorausgesetzt, der neue Text wäre nur eine leere Zeichenfolge) Wenn eine Rücktaste gedrückt wird, werden alle Zeichen gelöscht.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{ 
    //returns the "new text" of the field 
    NSString * text = [textField.text stringByReplacingCharactersInRange:range withString:string]; 
} 

Jede Hilfe wird sehr geschätzt.

Danke!

+0

Wenn die über den Parameter "' ersatzString: '" übergebene "' string "" eine leere Zeichenfolge mit der Länge null ist, während die '' range.length' "größer als null ist, würde ich sagen, dass es" alles ist geklärt werden ". –

+0

Wenn Sie nur eine Rücktaste drücken und ein Zeichen löschen, wird der Zeichenfolgenparameter leer und hat eine Länge von Null, so dass dies nicht funktioniert. Der Bereich – crizzwald

+0

kehrt zurück, als ob es sich um einen einzelnen Rückraum handelt. Das funktioniert also auch nicht. und ich bin nicht sicher, was Sie mit [Selbstlänge] meinen – crizzwald

Antwort

14

Ich benutze diese Lösung. Es benötigt keine lokalen Variablen und setzt die Cursorposition korrekt, nachdem das Zeichen gelöscht wurde.

Es ist ein Mashup dieser Lösungen:


- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
    { 
     if (range.location > 0 && range.length == 1 && string.length == 0) 
     { 
      // Stores cursor position 
      UITextPosition *beginning = textField.beginningOfDocument; 
      UITextPosition *start = [textField positionFromPosition:beginning offset:range.location]; 
      NSInteger cursorOffset = [textField offsetFromPosition:beginning toPosition:start] + string.length; 

      // Save the current text, in case iOS deletes the whole text 
      NSString *text = textField.text; 


      // Trigger deletion 
      [textField deleteBackward]; 


      // iOS deleted the entire string 
      if (textField.text.length != text.length - 1) 
      { 
       textField.text = [text stringByReplacingCharactersInRange:range withString:string]; 

       // Update cursor position 
       UITextPosition *newCursorPosition = [textField positionFromPosition:textField.beginningOfDocument offset:cursorOffset]; 
       UITextRange *newSelectedRange = [textField textRangeFromPosition:newCursorPosition toPosition:newCursorPosition]; 
       [textField setSelectedTextRange:newSelectedRange]; 
      } 

      return NO; 
     } 

     return YES; 
    } 
+0

sehr elegant. Ich mag das. – crizzwald

+0

Du bist ein Genie Bro !!! – Suran

5

dachte es schließlich für jedermann heraus schauen, um zu sehen, wie zu bestimmen, wann ein Backspace alle Zeichen eines sicheren UITextField klar wird:

UITextField:

self.passwordTextField 

Privatbesitz (initialisiert auf NO in init - wahrscheinlich nicht erforderlich):

self.passwordFirstCharacterAfterDidBeginEditing 

UITextFieldDelegate Methoden:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{ 
    //if text is blank when first editing, then first delete is just a single space delete 
    if([textField.text length] == 0 && self.passwordFirstCharacterAfterDidBeginEditing) 
     self.passwordFirstCharacterAfterDidBeginEditing = NO; 

    //if text is present when first editing, the first delete will result in clearing the entire password, even after typing text 
    if([textField.text length] > 0 && self.passwordFirstCharacterAfterDidBeginEditing && [string length] == 0 && textField == self.passwordTextField) 
    { 
     NSLog(@"Deleting all characters"); 
     self.passwordFirstCharacterAfterDidBeginEditing = NO; 
    } 
    return YES; 
} 

-(void)textFieldDidBeginEditing:(UITextField *)textField 
{ 
    if(textField == self.passwordTextField) 
    { 
     self.passwordFirstCharacterAfterDidBeginEditing = YES; 
    } 
} 

Ich hoffe, dass dies jemand hilft und ich hoffe auch, dass Apple nur eine Delegate-Methode erstellt, die aufgerufen wird, wenn ein sicheres Textfeld durch ein Löschen gelöscht wird - das scheint eine große umständliche, aber es funktioniert.

+0

Dies war die einzige Lösung, die für mich mit UITextFields in UITableViewCells eingebettet funktionierte. – Keller

3

Sichere Textfelder zur Bearbeitung auf iOS6 + beginnen klar, und zwar unabhängig davon, ob Sie das Löschen oder die Eingabe Text. Überprüfen, ob die Länge der Ersetzungszeichenfolge 0 ist, funktioniert, wenn das Textfeld von einer Rücktaste gelöscht wird, aber ärgerlicherweise sind die Werte für Bereich und Ersetzungszeichenfolge zu textField:shouldChangeCharactersInRange:replacementString: falsch, wenn der Text bei der Texteingabe gelöscht wird. Das war meine Lösung:

1) Registrieren Sie sich für textFieldTextDidChange Benachrichtigungen.

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(textFieldTextDidChange:) 
              name:UITextFieldTextDidChangeNotification 
              object:nil]; 

2) neu rufen Sie den textField:shouldChangeCharactersInRange:replacementString: Delegatmethode wenn das Textfeld sicher ist und gelöscht wurden.

- (void)textFieldTextDidChange:(NSNotification *)notification 
{ 
    if (textField.secureTextEntry && textField.text.length <= 1) { 
     [self.textField.delegate textField:self.textField 
      shouldChangeCharactersInRange:NSMakeRange(0, textField.text.length) 
         replacementString:textField.text]; 
    } 
} 
0

Posting meine alternative Lösung, wie ich das genaue Problem als OP hatte und ich fand keine Cursorposition Veränderung in der gewählten Antwort detailliert zu tun hatte.

Unten ist die UITextFieldDelegate-Methode, ich rufe eine benutzerdefinierte Delegate-Methode didChangeValueForTextField als meine Schaltfläche, die ich aktivieren möchte, ist außerhalb dieser Klasse.

Klasse Umsetzung UITextFieldDelegate

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 
NSString *newValue = [textField.text stringByReplacingCharactersInRange:range withString:string]; 
BOOL shouldReturn = YES; 

if (range.location > 0 && range.length == 1 && string.length == 0){ 
    [textField deleteBackward]; 

    if ([textField.text isEmptyCheck]) { // Check if textField is empty 
     newValue = @""; 
    } 

    shouldReturn = NO; 
} 

if(self.delegate && [self.delegate respondsToSelector:@selector(didChangeValueForField:withNewValue:)]) { 
    [self.delegate didChangeValueForField:textField withNewValue:newValue]; 
} 

return shouldReturn; 

}

Der Schlüssel war der Unterschied zwischen sicheren Bereich Einzelzeichenlöschung und sicheren Bereich einzelnes Zeichen Löschen erfassen, die Feld klar löst. Dies zu erkennen innerhalb die obige Delegate-Methode war notwendig.

Klasse enthält Knopf

- (void)didChangeValueForField:(UITextField *)textField withNewValue:(NSString *)value { 
    // Update values used to validate/invalidate the button. 
    // I updated a separate model here. 

    // Enable button based on validity 
    BOOL isEnabled = [self allFieldsValid]; // Check all field values that contribute to the button being enabled. 

    self.myButton.enabled = isEnabled; 

} 
0

Die akzeptierte Lösung nicht ermöglicht, eine Taste zu aktivieren. Es ändert tatsächlich das Backspace-Verhalten in einem sicheren Textfeld.

Diese Swift-Lösung löst die Frage, indem sie einen Delegaten korrekt über die tatsächliche Zeichenfolge informiert, die im textField festgelegt wird, auch wenn die Rücktaste gedrückt wird. Eine Entscheidung kann dann von diesem Delegierten getroffen werden.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 
    var shouldChange = true 

    if let text = textField.text { 
     let oldText = text.copy() 
     var resultString = (text as NSString).stringByReplacingCharactersInRange(range, withString: string) as NSString 
     let inputString = string as NSString 
     if range.location > 0 && range.length == 1 && inputString.length == 0 {//Backspace pressed 
       textField.deleteBackward() 
       shouldChange = false 

       if let updatedText = textField.text as NSString? { 
        if updatedText.length != oldText.length - 1 { 
         resultString = "" 
        } 
       } 
     } 
     self.delegate?.willChangeTextForCell(self, string: resultString as String) 
    } 

    return shouldChange 
} 
0

Swift-3

let text = textField.text 
     if string.length == 0{ 
      textField.deleteBackward() 
      if textField.text?.length != (text?.length)! - 1 { 
      //deleted whole word 

      } 
      return false // this is important 

     } 
0

swift3.0 - es funktioniert.

func textfield (_ textfield: UITextField, shouldChangeCharactersIn Bereich: NSRange, replacementString string: String) -> Bool {

if textField == passwordTextfield { 

     if range.location > 0 && range.length == 1 && string.characters.count == 0 { 

      if let textString = textField.text { 
       // iOS is trying to delete the entire string 
       let index = textString.index(textString.endIndex, offsetBy: -1) 
       textField.text = textString.substring(to: index) 
       return false 
      } 

     }else if range.location == 0 { 
      return true 
     }else { 
      if let textString = textField.text { 
       textField.text = textString + string 
       return false 
      } 
     } 


    } 
    return true 
} 
0

ich das gleiche Problem konfrontiert, wollte ich erkennen, wenn die Rück zu geht Löschen Sie alle Zeichen, damit ich einige andere Schaltflächen auf dem Bildschirm deaktivieren kann. So habe ich es geschafft.

-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField 
{ 
    _checkForDelete = NO; 
    if (textField.isSecureTextEntry && textField.text.length > 0) { 
     _checkForDelete = YES; 
    } 
    return YES; 
} 

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{ 
    if (_checkForDelete && string.length == 0) { 
     _checkForDelete = NO; 
     //Do whatever you want to do in this case, 
     //because all the text is going to be cleared. 
    } 
    return YES 
} 

Diese Lösung ist anders, weil es Sie Maßnahmen ergreifen können, wenn ein sicheres Feld bereits einen Text in ihm hat und Sie versuchen, es zu bearbeiten, sondern in der obigen Antwort akzeptiert, werden Sie in den Block gehen, selbst wenn Sie drücken die Rücktaste, während Sie bereits ein Feld bearbeiten, das den gesamten Text nicht löscht, sondern nur ein Zeichen löscht. Wenn Sie meine Methode verwenden, können Sie in diesem speziellen Fall eine Aktion ausführen, die sich jedoch nicht auf den nativen Fluss auswirkt.

Verwandte Themen