ios swift xcode6 subview uitextfielddelegate

ios - Botón Siguiente/Listo usando Swift con textFieldShouldReturn



xcode6 subview (4)

Estaba intentando probar mis campos de texto en SignUpWindowView.swift, que es donde se crean todos los campos de texto. Pero, como coloco SignUpWindowView en mi MainViewController como una subvista, todo mi "manejo" de UITextField tenía que hacerse en MainView y NO en su subvista.

Así que aquí está mi código completo (en este momento) para mi MainViewController, que se encarga de mover mi SignUpWindowView arriba / abajo cuando se muestra / oculta el teclado y luego se mueve de un campo al siguiente. Cuando el usuario se encuentra en el último campo de texto (cuyo botón Siguiente ahora está configurado como Hecho en la subvista), el teclado se retira y el usuario puede enviar el formulario con un botón de registro.

MainViewController:

import UIKit @objc protocol ViewControllerDelegate { func keyboardWillShowWithSize(size:CGSize, andDuration duration:NSTimeInterval) func keyboardWillHideWithSize(size:CGSize,andDuration duration:NSTimeInterval) } class ViewController: UIViewController,UITextFieldDelegate { var keyboardDelegate:ViewControllerDelegate? let signUpWindow=SignUpWindowView() let signUpWindowPosition:CGPoint=CGPointMake(505, 285) override func viewDidLoad() { super.viewDidLoad() // Keyboard Notifications NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil) // set the textFieldDelegates signUpWindow.firstNameTextField.delegate=self signUpWindow.lastNameTextField.delegate=self signUpWindow.userNameTextField.delegate=self signUpWindow.passwordTextField.delegate=self signUpWindow.confirmPasswordTextField.delegate=self signUpWindow.emailTextField.delegate=self } func keyboardWillShow(notification: NSNotification) { var info:NSDictionary = notification.userInfo! let keyboardFrame = info[UIKeyboardFrameEndUserInfoKey] as! NSValue let keyboardSize = keyboardFrame.CGRectValue().size var keyboardHeight:CGFloat = keyboardSize.height let animationDurationValue = info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber var animationDuration : NSTimeInterval = animationDurationValue.doubleValue self.keyboardDelegate?.keyboardWillShowWithSize(keyboardSize, andDuration: animationDuration) // push up the signUpWindow UIView.animateWithDuration(animationDuration, delay: 0.25, options: UIViewAnimationOptions.CurveEaseInOut, animations: { self.signUpWindow.frame = CGRectMake(self.signUpWindowPosition.x, (self.signUpWindowPosition.y - keyboardHeight+140), self.signUpWindow.bounds.width, self.signUpWindow.bounds.height) }, completion: nil) } func keyboardWillHide(notification: NSNotification) { var info:NSDictionary = notification.userInfo! let keyboardFrame = info[UIKeyboardFrameEndUserInfoKey] as! NSValue let keyboardSize = keyboardFrame.CGRectValue().size var keyboardHeight:CGFloat = keyboardSize.height let animationDurationValue = info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber var animationDuration : NSTimeInterval = animationDurationValue.doubleValue self.keyboardDelegate?.keyboardWillHideWithSize(keyboardSize, andDuration: animationDuration) // pull signUpWindow back to its original position UIView.animateWithDuration(animationDuration, delay: 0.25, options: UIViewAnimationOptions.CurveEaseInOut, animations: { self.signUpWindow.frame = CGRectMake(self.signUpWindowPosition.x, self.signUpWindowPosition.y, self.signUpWindow.bounds.width, self.signUpWindow.bounds.height) }, completion: nil) } func textFieldShouldReturn(textField: UITextField) -> Bool { switch textField { case signUpWindow.firstNameTextField: signUpWindow.lastNameTextField.becomeFirstResponder() break case signUpWindow.lastNameTextField: signUpWindow.userNameTextField.becomeFirstResponder() break case signUpWindow.userNameTextField: signUpWindow.passwordTextField.becomeFirstResponder() break case signUpWindow.passwordTextField: signUpWindow.confirmPasswordTextField.becomeFirstResponder() break case signUpWindow.confirmPasswordTextField: signUpWindow.emailTextField.becomeFirstResponder() break default: textField.resignFirstResponder() } return true } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func viewWillDisappear(animated: Bool) { NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil) } @IBAction func signup() { signUpWindow.frame=CGRectMake(signUpWindowPosition.x, signUpWindowPosition.y, 485,450) signUpWindow.backgroundColor=UIColor.clearColor() self.view.addSubview(signUpWindow) } }

Tengo una vista principal que agrega una subvista (signUpWindow) cuando se presiona un botón de registro.

En mi subvista SignUpWindow (SignUpWindowView.swift), configuro cada campo con una función, como ejemplo:

func confirmPasswordText() { confirmPasswordTextField.frame=CGRectMake(50, 210, 410, 50) confirmPasswordTextField.placeholder=("Confirm Password") confirmPasswordTextField.textColor=textFieldFontColor confirmPasswordTextField.secureTextEntry=true confirmPasswordTextField.returnKeyType = .Next confirmPasswordTextField.clearButtonMode = .WhileEditing confirmPasswordTextField.tag=5 self.addSubview(confirmPasswordTextField) }

Tengo el teclado moviendo el signUpWindow arriba y abajo cuando aparece y desaparece en la vista principal.

SignUpWindowView implementa el UITextFieldDelegate

Mi problema es que estoy tratando de configurar el botón Siguiente / Listo en el teclado y no estoy seguro de qué vista ( MainView o SignUpWindowView ) para agregar la función textFieldShouldReturn . He intentado ambos, pero ni siquiera puedo hacer una println para probar si la función se está ejecutando. Una vez que obtenga el textFieldShouldReturn para textFieldShouldReturn a disparar, estoy seguro de que puedo ejecutar el código necesario para que los botones Next / Done hagan lo que quiero, y publicaré la solución final para incluir la función Next / Done.

ACTUALIZADO para incluir una versión abreviada de SignUpWindowView.swift

import UIKit class SignUpWindowView: UIView,UITextFieldDelegate { let firstNameTextField:UITextField=UITextField() let lastNameTextField:UITextField=UITextField() override func drawRect(rect: CGRect){ func firstNameText(){ firstNameTextField.delegate=self firstNameTextField.frame=CGRectMake(50, 25, 200, 50) firstNameTextField.placeholder="First Name" firstNameTextField.returnKeyType = .Next self.addSubview(firstNameTextField) } func lastNameText(){ lastNameTextField.delegate=self lastNameTextField.frame=CGRectMake(260, 25, 200, 50) lastNameTextField.placeholder="Last Name" lastNameTextField.returnKeyType = .Done self.addSubview(lastNameTextField) } func textFieldShouldReturn(textField: UITextField!) -> Bool{ println("next button should work") if (textField === firstNameTextField) { firstNameTextField.resignFirstResponder() lastNameTextField.becomeFirstResponder() } return true } firstNameText() lastNameText() }


Usar etiquetas lo hace más fácil. Asigna etiquetas en orden ascendente a todos los campos de texto que estás utilizando en tu pantalla.

func textFieldShouldReturn(_ textField: UITextField) -> Bool { let textTag = textField.tag+1 let nextResponder = textField.superview?.viewWithTag(textTag) as UIResponder! if(nextResponder != nil) { //textField.resignFirstResponder() nextResponder?.becomeFirstResponder() } else{ // stop editing on pressing the done button on the last text field. self.view.endEditing(true) } return true }


DidEndOnExit (escribí esto desde la memoria, por lo que quizás no se llame exactamente como un evento UIControl similar) usando @IBAction y en esa función usa textF.resignFirstResponder() o .becomeFirstResponder()

EDITAR

UITextField es una subclase de UIControl y para agregar mediante programación un nuevo evento, use el método addTarget (). Ex:

func a(sender: AnyObject) {} textField.addTarget(self, action: "a:", forControlEvents: .EditingDidEndOnExit)

UIControl docs


UITextFieldDelegate implementar UITextFieldDelegate en su clase y establecer ese objeto como delegado para el UITextField . Luego implementa el método textFieldShouldReturn: así:

func textFieldShouldReturn(textField: UITextField) -> Bool { textField.resignFirstResponder() if textField == someTextField { // Switch focus to other text field otherTextField.becomeFirstResponder() } return true }

En tu ejemplo te falta esta línea:

confirmPasswordTextField.delegate = self

Si ha implementado el delegado por supuesto.