ios iphone swift xcode6

ios - Cambiar entre campos de texto al presionar la tecla de retorno en Swift



iphone xcode6 (14)

Estoy diseñando una aplicación para iOS y quiero que cuando presione la tecla de retorno en mi iPhone me dirija al siguiente campo de texto siguiente.

He encontrado un par de preguntas similares, con excelentes respuestas, pero todas están en Objective-C y estoy buscando el código Swift, ahora esto es lo que tengo hasta ahora:

func textFieldShouldReturn(emaillabel: UITextField) -> Bool{ return true }

Se coloca en el archivo que está conectado y el controlador a la UIView que contiene los campos de texto, pero no estoy seguro de si ese es el lugar correcto.

Básicamente soy nuevo en Swift, así que explique cada pequeño paso o me las arreglaré de alguna manera. También estoy usando la última versión de Xcode si eso hace alguna diferencia.

Bien, probé esto y obtuve este error:
//could not find an overload for ''!='' that accepts the supplied arguments

func textFieldShouldReturn(textField: UITextField) -> Bool { let nextTag: NSInteger = textField.tag + 1 // Try to find next responder let nextResponder: UIResponder = textField.superview!.viewWithTag(nextTag)! if (nextResponder != nil) { // could not find an overload for ''!='' that accepts the supplied arguments // Found next responder, so set it. nextResponder.becomeFirstResponder() } else { // Not found, so remove keyboard. textField.resignFirstResponder() } return false // We do not want UITextField to insert line-breaks. }

Gracias de antemano amigos!


Asegúrese de que sus delegados UITextField estén configurados y que las etiquetas se incrementen correctamente. Esto también se puede hacer a través del Creador de interfaces.

Aquí hay un enlace a una publicación de Obj-C que encontré: Cómo navegar por los campos de texto (botones Siguiente / Listo)

class ViewController: UIViewController,UITextFieldDelegate { //Link each UITextField @IBOutlet weak var textField: UITextField! override func viewDidLoad() { super.viewDidLoad() // Do this for each UITextField textField.delegate = self textField.tag = 0 //Increment accordingly } func textFieldShouldReturn(_ textField: UITextField) -> Bool { // Try to find next responder if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField { nextField.becomeFirstResponder() } else { // Not found, so remove keyboard. textField.resignFirstResponder() } // Do not add a line break return false } }


Este enfoque necesita algunos cambios en las vistas de tabla y vistas de colección, pero supongo que está bien para formularios simples.

Conecte sus textFields a una IBOutletCollection , IBOutletCollection por su coordenada y y en textFieldShouldReturn(_:) simplemente salte al siguiente campo de texto hasta llegar al final:

// MARK: UITextFieldDelegate func textFieldShouldReturn(_ textField: UITextField) -> Bool { switch textField { case nameTextField: phoneTextField.becomeFirstResponder() case phoneTextField: emailTextField.becomeFirstResponder() case emailTextField: descriptionTextField.becomeFirstResponder() default: textField.resignFirstResponder() } return false }

O simplemente mira el proyecto de muestra (xcode 7 beta 4)


He probado muchos códigos y finalmente esto funcionó para mí en Swift 3.0 Latest [marzo de 2017]

La clase "ViewController" debería heredar el "UITextFieldDelegate" para que este código funcione.

@IBOutlet var textFields: [UITextField]! ... textFields.sortInPlace { $0.frame.origin.y < $1.frame.origin.y } ... func textFieldShouldReturn(textField: UITextField) -> Bool { if let currentIndex = textFields.indexOf(textField) where currentIndex < textFields.count-1 { textFields[currentIndex+1].becomeFirstResponder() } else { textField.resignFirstResponder() } return true }

Agregue el campo de texto con el nuber de etiqueta adecuada y este número de etiqueta se usa para llevar el control al campo de texto apropiado según el número de etiqueta incremental asignado a él.

class ViewController: UIViewController,UITextFieldDelegate

En el código anterior, el "returnKeyType = UIReturnKeyType.next", donde hará que la tecla de retorno del teclado numérico se muestre como "Siguiente", también tiene otras opciones como "Unirse / Ir", etc., según su aplicación, cambie los valores.

Este "textFieldShouldReturn" es un método controlado por UITextFieldDelegate y aquí tenemos la siguiente selección de campo basada en el incremento del valor de Tag

override func viewDidLoad() { userNameTextField.delegate = self userNameTextField.tag = 0 userNameTextField.returnKeyType = UIReturnKeyType.next passwordTextField.delegate = self passwordTextField.tag = 1 passwordTextField.returnKeyType = UIReturnKeyType.go }


Le sugiero que use la instrucción switch en textFieldShouldReturn(_:) .

class ViewController: UIViewController, UITextFieldDelegate { @IBOutlet weak var txtFieldName: UITextField! @IBOutlet weak var txtFieldEmail: UITextField! @IBOutlet weak var txtFieldPassword: UITextField! override func viewDidLoad() { super.viewDidLoad() } func textFieldShouldReturn(_ textField: UITextField) -> Bool { if textField == txtFieldName { textField.resignFirstResponder() txtFieldEmail.becomeFirstResponder() } else if textField == txtFieldEmail { textField.resignFirstResponder() txtFieldPassword.becomeFirstResponder() } else if textField == txtFieldPassword { textField.resignFirstResponder() } return true } }


No hay ningún especial, aquí está mi uso actual para cambiar el textFiled. Entonces el código en ViewController se ve bien :). # Swift4

final class SomeTextFiled: UITextField { public var actionKeyboardReturn: (() -> ())? override init(frame: CGRect) { super.init(frame: frame) super.delegate = self } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) fatalError("init(coder:) has not been implemented") } func textFieldShouldReturn(_ textField: UITextField) -> Bool { self.resignFirstResponder() actionKeyboardReturn?() return true } } extension SomeTextFiled: UITextFieldDelegate {} class MyViewController : UIViewController { var tfName: SomeTextFiled! var tfEmail: SomeTextFiled! var tfPassword: SomeTextFiled! override func viewDidLoad() { super.viewDidLoad() tfName = SomeTextFiled(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) tfName.actionKeyboardReturn = { [weak self] in self?.tfEmail.becomeFirstResponder() } tfEmail = SomeTextFiled(frame: CGRect(x: 100, y: 0, width: 100, height: 100)) tfEmail.actionKeyboardReturn = { [weak self] in self?.tfPassword.becomeFirstResponder() } tfPassword = SomeTextFiled(frame: CGRect(x: 200, y: 0, width: 100, height: 100)) tfPassword.actionKeyboardReturn = { /// Do some further code } } }


Si tiene muchos componentes de campo de texto, podría ser mejor usar una colección de salida, vincular campos de texto y configurar la clave de retorno desde el generador de interfaces

@IBOutlet var formTextFields: [UITextField]! override func viewDidLoad() { for textField in formTextFields { textField.delegate = self } } extension RegisterViewController: UITextFieldDelegate { func textFieldShouldReturn(_ textField: UITextField) -> Bool { if let componentIndex = formTextFields.firstIndex(of: textField) { if textField.returnKeyType == .next, componentIndex < (formTextFields.count - 1) { formTextFields[componentIndex + 1].becomeFirstResponder() } else { textField.resignFirstResponder() } } return true } }


Simplemente use el método becomeFirstResponder() de la clase UIResponder en su método textFieldShouldReturn . Todos los objetos UIView son subclases de UIResponder .

func textFieldShouldReturn(_ textField: UITextField) -> Bool { if let nextField = self.view.viewWithTag(textField.tag + 1) as? UITextField { nextField.becomeFirstResponder() } else { textField.resignFirstResponder() } return false }

Puede encontrar más información sobre el método becomeFirstResponder() en Apple Doc''s here .


Tengo una buena solución para tu pregunta.

PASO:

1 - Establezca su clave de retorno del guión gráfico.

2 - En tu archivo rápido.

func textFieldShouldReturn(_ textField: UITextField) -> Bool { if textField.returnKeyType == .next { Email.resignFirstResponder() Password.becomeFirstResponder() } else if textField.returnKeyType == .go { Password.resignFirstResponder() self.Login_Action() } return true }

3 - No olvide configurar el delegado del campo de texto.

Gracias :)


Un método alternativo para los puristas que no les gusta usar etiquetas y quieren que el delegado UITextField sea la celda para mantener los componentes separados o unidireccionales ...

  1. Cree un nuevo protocolo para vincular Cell''s y TableViewController.

    protocol CellResponder { func setNextResponder(_ fromCell: UITableViewCell) }

  2. Agregue el protocolo a su celda, donde su Delegado TextField también es la celda (hago esto en el Guión gráfico).

    class MyTableViewCell: UITableViewCell, UITextFieldDelegate { var responder: CellResponder? func textFieldShouldReturn(_ textField: UITextField) -> Bool { responder?.setNextResponder(self) return true } }

  3. Haga que su TableViewController se ajuste al protocolo CellResponder (es decir, class MyTableViewController: UITableViewController, CellResponder ) e implemente el método que desee. Es decir, si tiene diferentes tipos de celdas, puede hacer esto, del mismo modo, puede pasar el IndexPath, usar una etiqueta, etc. No olvide establecer cell.responder = self en cellForRow ...

    func setNextResponder(_ fromCell: UITableViewCell) { if fromCell is MyTableViewCell, let nextCell = tableView.cellForRow(at: IndexPath(row: 1, section: 0)) as? MySecondTableViewCell { nextCell.aTextField?.becomeFirstResponder() } .... }


la forma más fácil de cambiar al siguiente campo de texto es que no es necesario un código largo

func textFieldShouldReturn(_ textField: UITextField) -> Bool { if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField { nextField.becomeFirstResponder() } else { textField.resignFirstResponder() return true; } return false }


La versión de Caleb en Swift 4.0

override func viewDidLoad() { super.viewDidLoad() emailTextField.delegate = self passwordTextField.delegate = self } func textFieldShouldReturn(_ textField: UITextField) -> Bool { if textField == emailTextField { passwordTextField.becomeFirstResponder() }else { passwordTextField.resignFirstResponder() } return true }

PS textField.superview? no funciona para mi


Rápido / Programáticamente

func textFieldShouldReturn(_ textField: UITextField) -> Bool { let txtTag:Int = textField.tag if let textFieldNxt = self.view.viewWithTag(txtTag+1) as? UITextField { textFieldNxt.becomeFirstResponder() }else{ textField.resignFirstResponder() } return true }


Swift 4.2

Esta es una solución más genérica y fácil , puede usar este código con cualquier cantidad de TextFields. Simplemente herede UITextFieldDelegate y actualice la etiqueta de campo de texto según el orden y copie esta función

if self.emaillabel.isEqual(self.anotherTextField) { self.anotherTextField.becomeFirstResponder() }


Swift 5

Puede cambiar fácilmente a otro TextField al hacer clic en la tecla de retorno en el teclado.

  • Primero, su controlador de vista se ajusta a UITextFieldDelegate y agrega el método delegado textFieldShouldReturn(_:) en ViewController
  • Arrastre desde TextField a ViewController en Interface Builder . Luego seleccione la opción delegate . Nota : haga esto para todos los TextField
  • Crear un IBOutlet para todos los TextFields

    func textFieldShouldReturn(_ textField: UITextField) -> Bool { let nextTag: NSInteger = textField.tag + 1 // Try to find next responder let nextResponder = textField.superview!.viewWithTag(nextTag) if (nextResponder != nil) { // could not find an overload for ''!='' that accepts the supplied arguments // Found next responder, so set it. nextResponder?.becomeFirstResponder() } else { // Not found, so remove keyboard. textField.resignFirstResponder() } return false // We do not want UITextField to insert line-breaks. }