2013-05-27 30 views
13

iOS 6'da güvenli bir metin alanına metin yazarsanız, başka bir metin alanına geçin, ardından güvenli metin alanına geri dönün ve geri al, tüm karakterler kaldırılır. Bununla birlikte ben iyiyim, ancak, bu güvenli metin alanının karakterleri içerip içermediğine bağlı olarak bir düğmeyi etkinleştirmeyi/devre dışı bırakmayı deniyorum. Alanlarda hangi karakterlerin bulunduğunu ve bir backspace'ın vurulduğunu nasıl belirleyeceğimi biliyorum ancak tüm karakterlerin temizlenme olup olmadığını nasıl belirleyeceğimi belirlerken sorun yaşıyorum.iOS 6 UITextField Güvenli - Tüm karakterleri temizlemek için arka plan nasıl algılanır?

Bu, bir alanın yeni metnini almak için kullandığım temsilci yöntemidir, ancak yeni metni nasıl alacağımı anlayamıyorum (yeni metnin yalnızca boş bir dize olacağını varsayarak) tüm karakterleri temizleyen bir backspace vurulursa.

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

Herhangi bir yardım çok takdir edilmektedir.

Teşekkürler!

+0

yoluyla geçirilen "' string'" eğer: "'range.length'" sıfırdan büyük ise "' replacementString '" parametresi sıfır uzunlukta boş bir dize, bunu senin "her şeydir söyleyebilirim Temizleniyor "durumda. –

+0

sadece bir backspace vurmak ve bir karakteri silmek string parametresinin boş olmasına ve sıfır uzunluğuna neden olacak, bu yüzden işe yaramayacaktır. – crizzwald

+0

aralığı, tek bir arka alanmış gibi döner, bu da işe yaramıyor. ve ben bu UITableViewCells gömülü UITextFields ile benim için çalıştı tek çözüm oldu – crizzwald

cevap

14

Bu çözümü kullanıyorum. Yerel değişkenlere ihtiyaç duymaz ve char'i sildikten sonra imleç konumunu doğru şekilde ayarlar.


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

çok zarif. Bunu sevdim. – crizzwald

+0

Sen bir dahisin Bro! – Suran

5

Son olarak bir geri al, güvenli bir UITextField tüm karakterleri silmek için giderken nasıl belirleneceğini görmek isteyen herkes için bunu anladım:

UITextField:

self.passwordTextField 

Özel mülkiyet (NO başlatıldı init - muhtemelen) gerekli değildir:

self.passwordFirstCharacterAfterDidBeginEditing 

UITextFieldDelegate Yöntemleri:

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

Umarım bu birisine yardımcı olur ve ayrıca Apple'ın güvenli bir metin alanı silme ile silindiğinde çağrılan bir temsilci yöntemi oluşturduğunu umuyorum - bu büyük bir hantal gibi görünüyor, ancak işe yarıyor.

+0

Eğer [öz uzunluğuna] ile ne demek emin değilim. – Keller

3

Güvenli metin alanları net üzerinde bakılmaksızın siliyor veya giriyorsanız olsun, iOS6 + 'da düzenlemeye başlayın:

Bu çözümler mashup var Metin. Metin alanı bir geri boşluktan temizlenirse, ancak metin değiştirilirse textField:shouldChangeCharactersInRange:replacementString: için aralık ve yedek dize parametreleri yanlışsa, yedek dizenin uzunluğunun 0 olup olmadığını kontrol eder. Bu benim çözümümdür: textFieldTextDidChange bildirimleri için kayıt olun. Metin alanı güvenlidir ve temizlenmiş olabilir eğer

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

2) textField:shouldChangeCharactersInRange:replacementString: temsilci yöntemini-çağırmak Re. Ben OP ile tam sorunu vardı ve ben seçilmiş cevap ayrıntılarıyla herhangi imleç pozisyonu değişiklik yapmak zorunda değildi bulduğumuz gibi

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

benim alternatif çözüm Gönderme.

Aşağıda, UITextFieldDelegate yöntemi var, etkinleştirmek istediğim düğmüm olarak bu sınıfın dışında bir özel temsilci yöntemi didChangeValueForTextField çağırıyorum. Anahtar alan net tetikleyen güvenli alan tek karakter silme ve güvenli alan tek karakter silme arasındaki farkı tespit edildi 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; 

}

uygulayan

Sınıf. Yukarıdaki delege yönteminde bu 'un içinde algılanması gerekliydi.

Sınıf içeren düğme bir düğmeye izin vermez

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

kabul çözüm sağlamaktır. Aslında güvenli bir metin alanında backspace davranışını değiştirir.

Bu Swift çözüm doğru geri tuşuna basıldığında dahil TextField, ayarlanabilir olan asıl dize hakkında bir temsilci bilgilendirerek soruyu çözmek yapar. Daha sonra bu delege tarafından bir karar verilebilir.

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 - çalışıyor.

fonk textField (_ textField: UITextField, shouldChangeCharactersIn aralığı: String: NSRange, dize replacementString) -> 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
Ben aynı sorunu bakıyordu

, ben geri silme gidiyor algılamak istedim Ekrandaki diğer bazı düğmeleri devre dışı bırakabilmek için tüm karakterleri temizle. Yani böyle başardım. güvenli bir alan zaten bir metin olduğunda harekete geçmek ve oldukça yukarıda kabul yanıtında, Bloğun bile gidecek, düzenlemek için çalışıyoruz sağlar çünkü

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

Bu çözüm farklıdır Zaten bir alanı düzenlerken, tüm metni temizlemeyecek, ancak sadece bir karakteri silen. Benim yöntemimi kullanarak bu özel durumda bir işlem yapmak için bir seçeneğiniz vardır, ancak doğal akışı da etkilemez.