Formateo de input de text seguro insertando espacios visibles

Quiero que el usuario ingrese un número de security social en el formatting ••• •• ••••. El usuario escribe los primeros 3 numbers, luego agrego un espacio manualmente. Luego ingresan 2 numbers más y agrego manualmente un espacio. Por supuesto, incluso los espacios se muestran como •. ¿Hay una forma nativa de cambiar este comportamiento? Actualmente estoy usando una funky implementación manual de esto.

¿Qué sucede si en lugar de espacios utiliza tres inputs de text diferentes? Luego, cuando cada usuario ingresa los primeros tres caracteres, ¿salta a la segunda input de text? Cuando escribe dos más, salta a la tercera input de text.

Aquí hay un ejemplo:

EDIT: ahora admite retroceso (gracias a @ triple-s).

extension ViewController: UITextFieldDelegate { func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { switch textField { // Jump forwards case self.textField1 where string.characters.count == 3 : self.textField2.becomeFirstResponder() case self.textField2 where string.characters.count == 2 : self.textField3.becomeFirstResponder() // Jump backwards case self.textField3 where string.characters.count == 0 : self.textField2.becomeFirstResponder() case self.textField2 where string.characters.count == 0 : self.textField1.becomeFirstResponder() default : break } return true } } 

Esto se puede lograr en un único campo de text como se le preguntó. Solo toqué "1", en el gif.

introduzca la descripción de la imagen aquí

  1. Usted selecciona su tipo de keyboard numérico (0-9), que puede asegurar que todo lo que se ingrese allí sea solo número.

  2. Luego puede adoptar el delegado textField e implementar el método de delegado

    func textField (textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {print (string)

     let char = string.cStringUsingEncoding(NSUTF8StringEncoding)! let isBackSpace = { return strcmp(char, "\\b") == -92} if (textField.text?.characters.count == 3 && !isBackSpace()) || (textField.text?.characters.count == 6 && !isBackSpace()){ textField.text = textField.text! + " " } if (textField.text?.characters.count) == 11 && !isBackSpace(){ ssnString = textField.text! self.view.endEditing(true) } return true 

    }

Esto incluye la lógica de agregar espacio después del tercer dígito si no está retrocediendo y lo mismo para el 6º dígito después.

Además, después de que el usuario ingrese 11 dígitos, no permitirá que el usuario ingrese más número como el formatting del SSN, después de que ingrese 11 dígitos, el SSN se saveá en ssnString, que se usará para su enmascaramiento especial.

  1. Debido a que no desea enmascarar el espacio, no podemos usar secureTextEntry. Entonces, en didEndEditing, le di una condición solo si el usuario ingresa el SSN completo, lo enmascararemos, lo que se puede modificar a cualquier escenario si lo desea. Pero creo que esto tiene más sentido.

func textFieldDidEndEditing(textField: UITextField) { if textField.text?.characters.count == 11 { maskSSNTextField() } }

En el método maskSSNTextField, func maskSSNTextField() { textField.text = "••• •• ••••" }

  1. Finalmente, debemos desenmascararlo cuando el usuario vuelve a él, si quieren cambiar el text

func textFieldDidBeginEditing(textField: UITextField) { if textField.text == "••• •• ••••"{ textField.text = ssnString } }

Esto cumplió con sus requisitos. Por favor avíseme si tiene alguna otra pregunta.

Cambié el método didChangeInRange para cumplir con su nuevo requisito, aunque creo que mi respuesta anterior podría funcionar. Ahora funciona como en el gif. Si desea que esté enmascarado, puede cambiar el código en textField si comenzó a editar.

introduzca la descripción de la imagen aquí

  func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let char = string.cStringUsingEncoding(NSUTF8StringEncoding)! let isBackSpace = { return strcmp(char, "\\b") == -92} if (textField.text?.characters.count == 3 && !isBackSpace()) || (textField.text?.characters.count == 6 && !isBackSpace()){ textField.text = textField.text! + " " ssnString = ssnString + " " } if isBackSpace() { ssnString = ssnString.substringToIndex(ssnString.endIndex.pnetworkingecessor()) }else { ssnString = ssnString + string print(ssnString) if ssnString.characters.count >= 2 { var starString = "" for i in 0...ssnString.characters.count-2 { if i==3 || i==6 { starString = starString+" " }else { starString = starString+"•" } } textField.text = "" print(ssnString.characters.last) textField.text = starString } } if (textField.text?.characters.count) == 11 && !isBackSpace(){ self.view.endEditing(true) } return true }