IOS 6 UITextField Secure - Як выявіць забой ачышчальнае ўсе знакі?

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

Любая дапамога вельмі шануецца.

Дзякуй!

14
толькі патрапіўшы ў забой і выдаленне аднаго знака прывядзе радковы параметр, каб быць пустым і мець нулявую даўжыню, так што не будзе працаваць.
дададзена аўтар crizzwald, крыніца
дыяпазоне вяртаецца, як быццам гэта адзін назад прастору, так што не працуе. і я не ўпэўнены, што вы маеце на ўвазе [даўжыня сябе]
дададзена аўтар crizzwald, крыніца
калі « радок » прайшоў у праз « replacementString: » параметру з'яўляецца пустая радок нулявы даўжыні у той час як « range.length » з'яўляецца больш за нуль, я б сказаў, што ваш «усе высякаюцца» выпадак.
дададзена аўтар Michael Dautermann, крыніца

7 адказы

Я выкарыстоўваю гэтае рашэнне. Ён не мае патрэбу ў лакальных зменных і ўстанаўлівае пазіцыю курсора правільна, пасля выдалення паўкокс.

Гэта Mashup гэтага рашэння:


 - (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;
    }
14
дададзена
вельмі элегантна. Мне падабаецца.
дададзена аўтар crizzwald, крыніца
Ты геній Bro !!!
дададзена аўтар Suran, крыніца

Нарэшце зразумеў гэта для тых, хто шукае, каб убачыць, як вызначыць, калі забой збіраецца ачысціць ўсе знакі бяспечнай UITextField:

UITextField:

self.passwordTextField

Прыватная ўласнасць (ініцыялізуецца NO у ініцыялізацыі - верагодна, не патрабуецца):

self.passwordFirstCharacterAfterDidBeginEditing

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

Я спадзяюся, што гэта дапаможа каму-то, і я таксама спадзяюся, што Apple, проста стварае метад дэлегаты, які выклікаецца, калі бяспечнае тэкставае поле чысціцца функцыя выдалення - гэта здаецца вялікім грувасткім, але гэта працуе.

5
дададзена
Гэта было адзіным рашэннем, якое працавала на мяне з UITextFields ўкаранёнага ў UITableViewCells.
дададзена аўтар Keller, крыніца

Бяспечныя тэкставыя палі ясна пачаць рэдагаванне на iOS6 +, незалежна ад таго, вы выдаляеце або ўвод тэксту. Праверка, калі даўжыня радка замены складае 0 работ, калі тэкставае поле чысціцца ад забой, але прыкра, дыяпазон і замена радкоў Параметрамі TextField: shouldChangeCharactersInRange: replacementString: няслушныя, калі тэкст чысціцца пры ўводзе тэксту. Гэта было маё рашэнне:

1) Рэгістрацыя для textFieldTextDidChange апавяшчэнняў.

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

2) Паўторна выклікаць TextField: shouldChangeCharactersInRange: replacementString: метад дэлегаты, калі тэкставае поле з'яўляецца бяспечным і можа быць ачышчаны.

- (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];
    }
}
3
дададзена

Я сутыкнулася з такім жа пытаннем, я хацеў бы выявіць, калі забой збіраецца ачысціць ўсе знакі, так што я магу быць уключаны адключыць некаторыя іншыя кнопкі на экране. Так што гэта, як я дасягнуў.

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

Гэтае рашэнне адрозніваецца тым, што дазваляе прымаць меры, калі абароненае поле ўжо маюць некаторы тэкст у ім, і вы спрабуеце змяніць яго, а ў вышэй прынятым адказе, вы будзеце ісці ў блоку, нават калі вы патрапілі забой, а ўжо рэдагуе поле, што не ачысціць ўвесь тэкст, а толькі выдаляе адзін знак. Выкарыстоўваючы мой метад, у вас ёсць магчымасць прыняць меры ў гэтым асаблівым выпадку, але гэта не паўплывае на роднай паток небудзь.

1
дададзена

swift3.0 - гэта працуе.

func textField(_ textField: UITextField, shouldChangeCharactersIn range: 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
}
1
дададзена

Прынятае рашэнне не дае магчымасці кнопкі. Гэта фактычна змяняе паводзіны забою на бяспечнай TextField.

Гэта рашэнне Swift сапраўды вырашае пытанне, ці правільна інфармуючы дэлегат аб фактычнай радку, якая будзе ўстаноўлена ў TextField, у тым ліку пры націску 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
}
0
дададзена

Праводка маё альтэрнатыўнае рашэнне, паколькі я меў дакладную праблему, як 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;

}
0
дададзена