fields - UITextField tiene espacios en blanco al final después de alternar SecureTextEntry
text field ios 11 (17)
Swift 4
El error está en el radar, también hay una explicación de la solución: http://www.openradar.me/38465011
Aquí está el corte de la solución temporal cómo actualizar de forma nativa la posición de cursor (cursor).
// update caret position
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
let (beginning, end) = (self.beginningOfDocument, self.endOfDocument)
self.selectedTextRange = self.textRange(from: beginning, to: end)
self.selectedTextRange = self.textRange(from: end, to: end)
}
Tengo un botón que alterna entre el modo Mostrar / Ocultar (es decir, alterna un UITextField entre secureTextEntry NO y YES). El objetivo de esto es permitir que el usuario vea la contraseña que está ingresando.
Seguí el ejemplo (con el mayor número de votos) aquí: UITextField secureTextEntry - funciona yendo de SÍ a NO, pero volver a SÍ no tiene ningún efecto
Sin embargo, cuando establezco secureTextEntry en NO, cualquier texto escrito allí termina con un espacio al final. Esto no parece ser un problema al establecer secureTextEntry en YES.
Por ejemplo, si ingreso el texto "mypassword" mientras setSecureTextEntry está establecido en NO, y luego lo cambio a YES, el usuario verá ********** (10 puntos), que es correcto. Si configuro SecureEnxtEntry en NO, el usuario verá "mypassword" (con un espacio al final, o al menos, el cursor se movió un espacio a la derecha).
Nota importante: en el depurador, el valor de cadena del texto aparece sin el espacio final, como este:
(lldb) expr self.passwordText.text
(NSString *) $0 = 0x1d8450e0 @"mypassword"
He intentado recortar el espacio en blanco ( evite espacios en blanco medios en UITextField ), pero no ha tenido ningún efecto.
Acabo de encontrarme con este caso y finalmente resolví este problema.
funciona en iOS SDK más reciente, iOS 8.1
En primer lugar, no hay espacio final en absoluto.
El carácter de punto (que se muestra en SecureEntry) y el carácter normal tienen ancho diferente y después de alternar el interruptor de entrada de seguridad, el cursor no actualiza su posición.
así que uso esta solución para resolver este problema.
- (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;
}
Swift 3+
// Workaround to refresh cursor
let currentText: String = self.userPassword.text!
self.userPassword.text = "";
self.userPassword.text = currentText
¡Espero eso ayude!
Aquí está la solución:
- (void)showHidePassword:(UIButton *)sender {
EDSignUpCell *cell = [self.signUpTblView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0]];
if(!TRIM_SPACE(cell.cellTextField.text).length) {return;}
[cell.showHidePasswordBtn setSelected:!cell.showHidePasswordBtn.isSelected];
cell.cellTextField.secureTextEntry = cell.showHidePasswordBtn.isSelected;
[cell.cellTextField setText:cell.cellTextField.text];
[cell.cellTextField becomeFirstResponder];
}
Cada vez que el texto se establece en UITextField, la posición del cursor se actualiza
Entonces usé este código
partial void btnShowPassword_ToutchUpInside (UIButton sender)
{
if (TxtPassword.SecureTextEntry == true) {
TxtPassword.SecureTextEntry = false;
TxtPassword.Text = TxtPassword.Text;
} else {
TxtPassword.SecureTextEntry = true;
}
}
Cuando cambiamos una propiedad textfield.secureTextEntry, la posición de intercalación no se actualiza. Para solucionar esto, el siguiente código solía funcionar antes de iOS 8:
pwdTextField.text = pwdTextField.text
Ahora no. Parece que iOS 8 detecta que el nuevo valor es igual al valor anterior y no hace nada. Entonces, para que funcione nuevamente, tenemos que cambiar el valor. Aquí está la versión rápida que funciona para mí.
let str = pwdTextField.text
pwdTextField.text = str + " "
pwdTextField.text = str
Esta es otra posibilidad para resolver este problema, donde self.passwordText es el UITextField:
if (self.passwordText.isFirstResponder) {
[self.passwordText resignFirstResponder];
[self.passwordText becomeFirstResponder];
}
Este trabajo para mí en 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;
}
Esto funciona en mi caso
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];
Estoy usando esto, funciona bien.
[self.yourTextField becomeFirstResponder];
Extensión Swift UITextField:
extension UITextField {
func toggleSecureEntry() {
let wasFirstResponder = isFirstResponder()
if wasFirstResponder { resignFirstResponder() }
secureTextEntry = !secureTextEntry
if wasFirstResponder { becomeFirstResponder() }
}
}
Establecer la solución textField.text también funciona en algunas situaciones, pero no para mi necesidad (Fuente personalizada con dos campos de texto. Cambios de fuente causados y fallas en el tiempo de ejecución). Agregar aquí también.
func toggleSecureEntry() {
secureTextEntry = !secureTextEntry
let originalText = text
text = nil
text = originalText
}
PRE-iOS-8.0 (solución anticuada) ... En el método de acción de su botón (alternar entre secureTextEntry
SÍ y NO), simplemente establezca la propiedad de text
UITextField
en su valor de text
actual. Aunque esto puede parecer redundante y un poco como un hack, esto volverá a dibujar el cursor en la posición correcta. Aquí hay un ejemplo de cómo debería verse el método de acción de su botón ahora ...
-(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 ... A partir de iOS 8.0, parece que el UITextField
de text
UITextField
ya no vuelve a dibujar el cursor cuando se le llama con una cadena igual a su valor de cadena actual. Ahora, debemos llevar esto un paso más allá y realmente cambiar el valor del text
antes de restablecerlo nuevamente. Reemplace el setText:
anterior setText:
línea con algo así como estas líneas.
// * 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
Para hacer que el cursor se reposicione correctamente, la configuración de los atributos de la fuente pareció hacer el truco para mí.
// Hack to update cursor position
self.passwordTf.defaultTextAttributes = @{NSFontAttributeName: textFieldFont, NSForegroundColorAttributeName: textFieldColor};
// Change secure entry
self.passwordTf.secureTextEntry = !self.passwordTf.secureTextEntry;
Probado en iOS8, iOS9. ¡Espero eso ayude!
Para solucionar este error en iOS, simplemente puede hacer lo siguiente (funciona para cualquier versión de iOS):
- (IBAction)toggleSecureTextEntry:(UIButton *)button
{
self.textField.secureTextEntry = !self.textField.secureTextEntry;
NSString *originalText = self.textField.text;
self.textField.text = nil;
self.textField.text = originalText;
}
Parece que la segunda solución en el enlace al que se hace referencia, cuando se implementa, tiene el comportamiento deseado de no agregar un espacio adicional:
https://.com/a/8495888/738190
Puedes arreglarlo así:
NSString *currentText = self.textfield.text;
self.textfield.text = @"";
self.textfield.text = currentText;
Tengo una solución limpia que no se ensucia con la propiedad de text
de UITextField
.
Envuélvelos en este estilo.
[self.passwordTextField resignFirstResponder]; // first resign its first responder.
// change `secureTextEntry` property''s 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.
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]];
Esto es lo que usé para iOS 8