Подтвердить что ты не робот

UITextField secureTextEntry - работает от YES до NO, но возврат к YES не влияет

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

EDIT: Я считаю, что эта проблема исправлена ​​с iOS5.

4b9b3361

Ответ 1

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

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

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

    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 = ""
    }

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

Ответ 2

Решение Mike R приятно, но я предпочитаю этот подход:

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

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

Ответ 3

Я вошел в 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) {
            // http://stackoverflow.com/questions/1317929/insert-string-at-cursor-position-of-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;
}

Ответ 4

С iOS вы никогда не должны пытаться "взломать" вещи, если поведение, которое вы хотите, не предусмотрено каркасом, передумайте!

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

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

Ответ 5

Быстрая версия Sandy-решения.

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