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), но это не повлияло.
Ответы
Ответ 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];