UITextField secureTextEntry - работает с ДА на НЕТ, но переключение обратно на ДА не имеет никакого эффекта - PullRequest
27 голосов
/ 15 июля 2011

Вышесказанное говорит само за себя - у меня UITextField настроен как безопасный, но я хочу дать пользователям возможность сделать его небезопасным (чтобы они могли точно видеть, что они печатали, если они находятся в приватной области).Однако предположим, что они по ошибке нажали на тумблер и хотят вернуть его обратно в безопасный режим?Это не работает.Я попробовал все - используя -1 вместо YES, удаляя текст и затем возвращая его.Я в полной растерянности от других идей.[Введенный rdar: // 9781908]

РЕДАКТИРОВАТЬ: я считаю, что эта проблема исправлена ​​с iOS5.

Ответы [ 5 ]

47 голосов
/ 21 августа 2011

Это должно быть проблемой фокуса ввода: когда фокус, UITextField может изменить только ON-> OFF.
Попробуйте следующий трюк, чтобы переключить OFF-> ON:

textField.enabled = NO;
textField.secureTextEntry = YES;
textField.enabled = YES;
[textField becomeFirstResponder];

EDIT (dhoerl): В iOS 9.3 я обнаружил, что это работает, но есть проблема.Если вы введете, скажем, 3 символа в обычном виде, затем переключитесь на защищенный текст, затем введите символ, 3 ранее существовавших символа исчезнут.Я попробовал все виды трюков, чтобы очистить, а затем сбросить текст без успеха.Я наконец попытался просто поиграть с управлением, вырезав и вставив - вставка в недавно переключенный в защищенный режим работала отлично.Так что я эмулировал это в коде, и теперь все работает нормально - не нужно играть с респондентом.Вот что я наконец-то получил:

    if textview should go into secure mode and the textfield is not empty {
        textField.text = ""
        textField.secureTextEntry = true

        UIPasteboard.generalPasteboard().string = password
        textField.paste(self)
        UIPasteboard.generalPasteboard().string = ""
    }

Я бы предпочел не делать эту вставку, но если вы хотите, чтобы она была бесшовной, это единственный способ найти это.

23 голосов
/ 14 декабря 2011

Решение Майка Р это хорошо, но я предпочитаю такой подход:

BOOL wasFirstResponder;
if ((wasFirstResponder = [passwordField isFirstResponder])) {
    [passwordField resignFirstResponder];
}
// In this example, there is a "show password" toggle
[passwordField setSecureTextEntry:![passwordField isSecureTextEntry]];
if (wasFirstResponder) {
    [passwordField becomeFirstResponder];
}

Таким образом, вы снова становитесь первым ответчиком, когда это необходимо.

1 голос
/ 18 июля 2011

Я вошел в rdar против этой проблемы, но нашел способ обойти. По сути, вы должны программно заменить «застрявший» элемент управления на новый. Самое простое, что нужно сделать, это заархивировать существующий элемент управления в viewDidLoad, а затем разархивировать при необходимости:

// do in viewDidLoad
self.passwordMemberArchive = [NSMutableData data];
NSKeyedArchiver *ka = [[NSKeyedArchiver alloc]       initForWritingWithMutableData:passwordMemberArchive];
[ka encodeObject:password];
[ka finishEncoding];
[ka release];


    // In the action method when you get the UISwitch action message ---
// when your switch changes state
if(isOn) {
    NSString *text = [NSString stringWithString:password.text];
    NSKeyedUnarchiver *kua = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    UITextField *tf = [kua decodeObject];
    [kua finishDecoding];
    [kua release];
    tf.inputAccessoryView = textField.inputAccessoryView;
    tf.frame = textField.frame;

    BOOL isFirstResponder = [textField isFirstResponder];
    [scrollView insertSubview:tf aboveSubview:textField];
    if(isFirstResponder) {
        [tf becomeFirstResponder];
    }

    [textField removeFromSuperview];
    self.password = tf;

    if([text length]) {
        if(isFirstResponder) {
            // /994473/vstavit-stroku-v-pozitsiy-kursora-uitextfield
            // Get a reference to the system pasteboard
            UIPasteboard* lPasteBoard = [UIPasteboard generalPasteboard];
            // Save the current pasteboard contents so we can restore them later
            NSArray* lPasteBoardItems = [lPasteBoard.items copy];
            // Update the system pasteboard with my string
            lPasteBoard.string = text;
            // Paste the pasteboard contents at current cursor location
            [tf paste:self];
            // Restore original pasteboard contents
            lPasteBoard.items = lPasteBoardItems;
            [lPasteBoardItems release];
        } else {
            tf.text = text;
        }
    }
} else {
    textField.secureTextEntry = NO;
}
0 голосов
/ 30 мая 2016

Свифт версия решения Сэнди.

if #available(iOS 9.2, *) {
    passwordTextField.secureTextEntry = !passwordTextField.secureTextEntry
}
else {
    let wasFirstResponder = passwordTextField.isFirstResponder()
    if wasFirstResponder {
        passwordTextField.resignFirstResponder()
    }

    passwordTextField.secureTextEntry = !passwordTextField.secureTextEntry
    if wasFirstResponder {
        passwordTextField.becomeFirstResponder()
    }
}
0 голосов
/ 24 сентября 2013

С iOS вы никогда не должны пытаться «взломать» что-либо, если желаемое поведение не обеспечивается фреймворком, передумайте!

Сначала это проще ^^, во-вторых, пользователь не будет реагировать на это, затем вы никогда не узнаете, сломает ли это следующее обновление iOS или нет, поэтому это может быть опасно для вашего приложения.

«Вы хотите, чтобы пользователь видел пароль, который он вводит в защищенном текстовом поле», вместо этого вы можете отобразить UILabel внизу? Или окно подтверждения с ясным паролем?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...