Cocoa touch iOS 6 UITextField安全-如何检测清除所有字符的退格?

Cocoa touch iOS 6 UITextField安全-如何检测清除所有字符的退格?,cocoa-touch,ios6,uitextfield,uitextfielddelegate,Cocoa Touch,Ios6,Uitextfield,Uitextfielddelegate,在iOS 6中,如果在安全文本字段中键入文本,请更改为另一个文本字段,然后返回安全文本字段并单击backspace,所有字符都将被删除。我对这种情况很满意,但是,我正在尝试根据此安全文本字段是否包含字符来启用/禁用按钮。我知道如何确定字段中有哪些字符,以及是否命中了退格,但我很难确定如何检测是否正在清除所有字符 这是我用来获取字段新文本的委托方法,但是,如果单击清除所有字符的退格符,我似乎不知道如何获取新文本(假设新文本只是一个空白字符串) - (BOOL)textField:(UITextFi

在iOS 6中,如果在安全文本字段中键入文本,请更改为另一个文本字段,然后返回安全文本字段并单击backspace,所有字符都将被删除。我对这种情况很满意,但是,我正在尝试根据此安全文本字段是否包含字符来启用/禁用按钮。我知道如何确定字段中有哪些字符,以及是否命中了退格,但我很难确定如何检测是否正在清除所有字符

这是我用来获取字段新文本的委托方法,但是,如果单击清除所有字符的退格符,我似乎不知道如何获取新文本(假设新文本只是一个空白字符串)

- (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];
}
非常感谢您的帮助


谢谢

对于任何想知道如何确定退格何时将清除安全UITextField的所有字符的人来说,终于找到了答案:

self.passwordTextField
UITextField:

self.passwordTextField
私有属性(在init中初始化为NO-可能不需要):

UITextFieldDelegate方法:

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

我希望这对某些人有所帮助,我也希望苹果只是创建了一个委托方法,当安全文本字段被删除清除时调用该方法-这看起来很麻烦,但它可以工作。

我使用这个解决方案。删除字符后,它不需要局部变量,并正确设置光标位置

这是这些解决方案的混合:


在iOS6+上开始编辑时清除安全文本字段,无论您是删除还是输入文本。如果文本字段已从退格中清除,则检查替换字符串的长度是否为0会起作用,但令人烦恼的是,如果在输入文本时清除了文本,则
textField:shouldChangeCharactersRange:replacementString:
的范围和替换字符串参数不正确。这就是我的解决方案:

1) 注册
textFieldTextDidChange
通知

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(textFieldTextDidChange:)
                                             name:UITextFieldTextDidChangeNotification
                                           object:nil];
2) 如果文本字段是安全的并且可能已被清除,请重新调用
textField:shouldChangeCharactersRange:replacementString:
delegate方法

- (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];
    }
}
-(void)textFieldTextDidChange:(NSNotification*)通知
{

if(textField.secureTextEntry&&textField.text.length发布我的替代解决方案,因为我的确切问题是OP,并且发现我不必执行所选答案中详细说明的任何光标位置更改

下面是UITextFieldDelegate方法,我调用了一个自定义委托方法didChangeValueForTextField,因为我要启用的按钮不在此类中

类实现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;
 - (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;

}
}

关键是检测安全字段单字符删除和触发字段清除的安全字段单字符删除之间的差异。在上述委托方法中检测这一点是必要的

包含启用按钮的类

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

}

接受的解决方案不启用按钮。它实际上会更改安全文本字段上的退格行为

这个快速的解决方案通过正确地通知一个代表将在文本字段中设置的实际字符串(包括按backspace时)来解决问题。然后,该代表可以做出决定

    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
}
swift3.0-它可以工作

func textField(textField:UITextField,shouldChangeCharacters范围:NSRange,replacementString: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
}

我也面临同样的问题,我想检测退格何时会清除所有字符,这样我就可以启用或禁用屏幕上的其他按钮。这就是我如何实现的

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

这个解决方案是不同的,因为它允许你在一个安全字段中已经有一些文本并且你正在试图编辑它时采取行动,而不是在上面接受的答案中,即使你在编辑一个字段时点击backspace,你也会进入块中,这不会清除整个文本,而只会删除一个字符。使用我的方法,你可以我可以选择在这种特殊情况下执行操作,但它也不会影响本机流。

如果通过“
replacementString:
”参数传入的“
字符串
”是长度为零的空字符串,而“
range.length
”大于零,我会说这是您的“正在清除所有内容”case.只需点击一个backspace并删除一个字符,将导致string参数为空且长度为零,因此这不起作用。range返回时就像它是一个单个back space,因此也不起作用。我不确定您所说的[self length]是什么意思这是唯一一个在UITableViewCells中嵌入UITextFields的解决方案。