J'ai une vue principale qui ajoute une sous-vue (signUpWindow) lorsqu'un bouton d'inscription est enfoncé.
Dans ma sous-vue signUpWindow (SignUpWindowView.Swift), j'ai configuré chaque champ avec une fonction, par exemple:
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)
}
J'ai le clavier qui déplace le signe UpWindow de haut en bas lorsqu'il apparaît et disparaît dans la vue principale.
SignUpWindowView
implémente le UITextFieldDelegate
Mon problème est que j'essaie de configurer le bouton Suivant/Terminé du clavier et je ne sais pas quelle vue (MainView
ou SignUpWindowView
) ajouter la fonction textFieldShouldReturn
. J'ai essayé les deux, mais je n'arrive même pas à déclencher un println
pour tester si la fonction est même en cours d'exécution. Une fois le textFieldShouldReturn
déclenché, je suis convaincu que je peux exécuter le code nécessaire pour que les boutons Next/Done fassent ce que je veux et publierai la solution finale pour inclure la fonction Next/Done.
MIS À JOUR pour inclure une version abrégée 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()
}
J'essayais de tester mes champs de texte dans SignUpWindowView.Swift, où tous les textFields sont créés. Mais, puisque je place SignUpWindowView dans mon MainViewController en tant que sous-vue, toute ma "gestion" UITextField devait être effectuée dans le MainView et NON dans sa sous-vue.
Voici donc tout mon code (pour le moment) pour mon MainViewController, qui gère le déplacement de mon SignUpWindowView vers le haut/bas lorsque le clavier est affiché/masqué, puis passe d'un champ à l'autre. Lorsque l'utilisateur se trouve dans le dernier champ de texte (dont le bouton Suivant du clavier est désormais défini sur Terminé dans la sous-vue), le clavier se replie et l'utilisateur peut ensuite envoyer le formulaire avec un bouton d'inscription.
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)
}
}
Vous devez implémenter UITextFieldDelegate
dans votre classe et définir cet objet comme délégué pour le UITextField
. Ensuite, implémentez la méthode textFieldShouldReturn:
comme ça:
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
if textField == someTextField { // Switch focus to other text field
otherTextField.becomeFirstResponder()
}
return true
}
Dans votre exemple, il vous manque cette ligne:
confirmPasswordTextField.delegate = self
Si vous avez implémenté le délégué, bien sûr.
L'utilisation de balises facilite la tâche. Attribuez des balises dans l'ordre croissant à tous les champs de texte que vous utilisez sur votre écran.
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
}
Vous connectez le DidEndOnExit
(j'ai écrit cela de mémoire donc peut-être que ce n'est pas appelé exactement mais similaire) UIControl
événement en utilisant un @IBAction
Et dans ce func vous utilisez textF.resignFirstResponder()
ou .becomeFirstResponder()
UITextField est une sous-classe d'UIControl et pour ajouter par programme un nouvel événement, vous utilisez la méthode addTarget (). Ex:
func a(sender: AnyObject) {}
textField.addTarget(self, action: "a:", forControlEvents: .EditingDidEndOnExit)