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

UITextField имеет завершающий пробел после переключения secureTextEntry

У меня есть кнопка, которая переключается между режимом Show/Hide (т.е. переключает UITextField между secureTextEntry NO и YES). Целью этого является позволить пользователю увидеть введенный пароль.

Я следовал примеру (с наибольшим количеством голосов) здесь: UITextField secureTextEntry - работает от YES до NO, но возврат к YES не имеет эффекта

Однако, когда я устанавливаю secureTextEntry в NO, любой текст, который был там написан, заканчивается пробелом в конце. Это не кажется проблемой при настройке secureTextEntry на YES.

Например, если я введу текст "mypassword", а setSecureTextEntry - "НЕТ", а затем переключится на "YES", пользователь увидит ********** (10 точек), что верно, Если я установилSecureTextEntry в НЕТ, пользователь увидит "mypassword" (с пробелом в конце или, по крайней мере, курсор переместил одно пространство вправо).

Важное примечание: В отладчике строковое значение текста выглядит без конечного пространства, например:

(lldb) expr self.passwordText.text
(NSString *) $0 = 0x1d8450e0 @"mypassword"

Я пробовал обрезать пробелы (за избегать промежуточных пробелов в UITextField), но это не повлияло.

4b9b3361

Ответ 1

Я только что столкнулся с этим делом и, наконец, решил эту проблему.

работает над последним IOS SDK, iOS 8.1

Прежде всего, нет конечного пространства вообще.

Символ точки (показан в SecureEntry) и обычный символ имеют разную ширину, и после переключения переключателя isSecureEntry курсор не обновил его положение.

поэтому я использую это решение для решения этой проблемы.

- (void)toggle
{
    NSString *tmpString;
    [self.passwordTextField setSecureTextEntry:!self.passwordTextField.isSecureTextEntry];
    if (self.passwordTextField.isSecureTextEntry) {
       // do stuffs
    } else {
       // do other stuffs
    }
    // Workaround to refresh cursor
    tmpString = self.passwordTextField.text;
    self.passwordTextField.text = @" ";
    self.passwordTextField.text = tmpString;
}

надеюсь, что это поможет!

Ответ 2

PRE-iOS-8.0 (устаревшее решение)... В вашем методе действий кнопки (переключение между secureTextEntry YES и NO) просто установите для свойства UITextField text его текущее значение text. Хотя это может показаться излишним и немного похож на хак, это приведет к перерисовке курсора в правильном положении. Вот пример того, как теперь будет выглядеть метод действия вашей кнопки...

-(void)toggleButtonPressed:(UIButton*)sender
{
    // Toggle between secure and not-so-secure entry
    self.toggleButton.selected = !self.toggleButton.selected;
    self.textfield.secureTextEntry = !self.toggleButton.selected;

    // * Redundant (but necessary) line *
    [self.textfield setText:self.textfield.text];
}

POST-iOS-8.0... Как видно из iOS 8.0, установщик UITextField text больше не перерисовывает курсор при вызове со строкой, равной ее текущему строковому значению. Теперь нам нужно сделать еще один шаг и фактически изменить значение text перед повторным его сбросом. Замените приведенную выше строку setText: на что-то вроде этих строк.

// * Extra redundant (but necessary) lines *
NSString *currentText = self.textfield.text;
[self.textfield setText:@"Arbitrary string..."]; // Change the value
[self.textfield setText:currentText]; // Reset the value

Ответ 3

Чтобы обойти эту ошибку в iOS, вы можете просто сделать следующее (работает для любой версии iOS):

- (IBAction)toggleSecureTextEntry:(UIButton *)button
{
    self.textField.secureTextEntry = !self.textField.secureTextEntry;
    NSString *originalText = self.textField.text;
    self.textField.text = nil;
    self.textField.text = originalText;
}

Ответ 4

Эта работа для меня на iOS 8

if (self.passwordTextField.secureTextEntry) {
    // Display password and keep selected text range
    UITextRange *selectedTextRange = self.passwordTextField.selectedTextRange;
    NSString *password = self.passwordTextField.text;
    self.passwordTextField.secureTextEntry = NO;
    self.passwordTextField.text = [@"" stringByPaddingToLength:password.length withString:@" " startingAtIndex:0]; // Done for carret redrawing
    self.passwordTextField.text = password;
    self.passwordTextField.selectedTextRange = selectedTextRange;
}
else {
    // Hide password and keep selected text range
    UITextRange *selectedTextRange = self.passwordTextField.selectedTextRange;
    NSString *password = self.passwordTextField.text;
    self.passwordTextField.secureTextEntry = YES;
    self.passwordTextField.text = [@"" stringByPaddingToLength:password.length withString:@" " startingAtIndex:0]; // Done for carret redrawing
    self.passwordTextField.text = password;
    self.passwordTextField.selectedTextRange = selectedTextRange;
}

Ответ 5

UITextPosition *beginning = [self.passwordField beginningOfDocument];
[self.passwordField setSelectedTextRange:[self.passwordField textRangeFromPosition:beginning
                                                                        toPosition:beginning]];

UITextPosition *end = [self.passwordField endOfDocument];
[self.passwordField setSelectedTextRange:[self.passwordField textRangeFromPosition:end
                                                                        toPosition:end]];

Это то, что я использовал для iOS 8

Ответ 6

Когда мы меняем свойство textfield.secureTextEntry, позиция каретки не обновляется. Чтобы исправить это, приведенный ниже код используется для работы до IOS 8:

pwdTextField.text  = pwdTextField.text

Теперь это не так. Кажется, что IOS 8 обнаруживает, что новое значение равно старому значению и ничего не делает. Поэтому, чтобы заставить его работать снова, мы должны фактически изменить значение. Вот быстрая версия, которая работает для меня.

let str = pwdTextField.text
pwdTextField.text = str + " "
pwdTextField.text = str

Ответ 7

Это еще одна возможность решить эту проблему, где self.passwordText - это UITextField:

if (self.passwordText.isFirstResponder) {
    [self.passwordText resignFirstResponder];
    [self.passwordText becomeFirstResponder];
}

Ответ 8

Вы можете исправить это следующим образом:

NSString *currentText = self.textfield.text;
self.textfield.text = @"";
self.textfield.text = currentText;

Ответ 9

У меня есть чистое решение, не загрязняющееся с text свойством UITextField.

Оберните их в этом стиле.

[self.passwordTextField resignFirstResponder]; // first resign its first responder.

// change `secureTextEntry` property value if necessary.

if (self.passwordTextField.secureTextEntry) {
    self.passwordTextField.secureTextEntry = NO;
    self.passwordEcryptButton.selected = YES;
}else{
    self.passwordTextField.secureTextEntry = YES;
    self.passwordEcryptButton.selected = NO;
}

[self.passwordTextField becomeFirstResponder];  // finally gain its first responder again.

Ответ 10

Похоже, что второе решение в ссылочной ссылке, когда оно реализовано, имеет желаемое поведение, не добавляя дополнительное пространство:

fooobar.com/questions/199204/...

Ответ 11

Это работает в моем случае

    BOOL wasFirstResponder = [self.passwordTextField isFirstResponder];
    if([self.passwordTextField isSecureTextEntry])
    {
        //This three lines are key
        self.passwordTextField.delegate = nil;
        [self.passwordTextField resignFirstResponder];
        self.passwordTextField.delegate = self;
    }

    [self.passwordTextField setSecureTextEntry: !self.passwordTextField.isSecureTextEntry];
    if(wasFirstResponder)
        [self.passwordTextField becomeFirstResponder];

Ответ 12

Быстрое расширение UITextField:

extension UITextField {
    func toggleSecureEntry() {
        let wasFirstResponder = isFirstResponder()

        if wasFirstResponder { resignFirstResponder() }
        secureTextEntry = !secureTextEntry
        if wasFirstResponder { becomeFirstResponder() }
    }
}

Настройка textField.text решение также работает в некоторых ситуациях, но не для моей потребности (пользовательский шрифт с двумя текстовыми полями. Причиненные изменения шрифта и сбои во время выполнения.) Добавление здесь тоже.

func toggleSecureEntry() {
    secureTextEntry = !secureTextEntry
    let originalText = text
    text = nil
    text = originalText
}

Ответ 13

Чтобы правильно переместить курсор, установка атрибутов шрифта показала мне трюк.

// Hack to update cursor position
self.passwordTf.defaultTextAttributes = @{NSFontAttributeName: textFieldFont, NSForegroundColorAttributeName: textFieldColor};

// Change secure entry
self.passwordTf.secureTextEntry = !self.passwordTf.secureTextEntry;

Протестировано на iOS8, iOS9. Надеюсь, это поможет!

Ответ 14

Каждый раз, когда текст задается в UITextField, обновление курсора обновляется

Итак, я использовал этот код

partial void btnShowPassword_ToutchUpInside (UIButton sender)
    {
        if (TxtPassword.SecureTextEntry == true) {
            TxtPassword.SecureTextEntry = false;
            TxtPassword.Text = TxtPassword.Text;
        } else {
            TxtPassword.SecureTextEntry = true;
        }
    }

Ответ 15

Я использую это, отлично работает. Счастливое кодирование

    [self.yourTextField becomeFirstResponder];