web-dev-qa-db-fra.com

Bouton Suivant / Terminé utilisant Swift avec textFieldShouldReturn

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()
}
25
Amy Plant

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)
    }
}
11
Amy Plant

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.

38
Stefan Salatic

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
}
7
PhaniBhushan kolla

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()


MODIFIER

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)

documents UIControl

1
Arbitur