Przycisk Next / Done za pomocą Swift z textFieldShouldReturn

Mam MainView, który dodaje subview (signUpWindow) po naciśnięciu przycisku rejestracji.

In my signUpWindow subview (SignUpWindowView.swift), ustawiłem każde pole za pomocą funkcji, jako przykład:

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

Mam klawiaturę przesuwającą okno rejestracji w górę iw dół, gdy pojawia się i znika w widoku głównym.

SignUpWindowView implementuje UITextFieldDelegate

Mój problem polega na tym, że próbuję skonfigurować przycisk Next / Done na klawiaturze i nie jestem pewien, który Widok (MainView lub SignUpWindowView) aby dodać funkcję textFieldShouldReturn. Próbowałem obu, ale nie mogę nawet uzyskać println, aby odpalić, aby sprawdzić, czy funkcja jest w ogóle wykonywana. Po uruchomieniu textFieldShouldReturn jestem pewien, że mogę wykonać niezbędny kod, aby uzyskać przyciski Next / Done, aby zrobić to, co chcę, i opublikuję ostateczne rozwiązanie, aby uwzględnić funkcję Next / Done.

Zaktualizowano o skróconą wersję 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()
}
Author: Tomáš Hübelbauer, 2015-04-28

4 answers

Musisz zaimplementować UITextFieldDelegate w swojej klasie i ustawić ten obiekt jako delegat dla UITextField. Następnie zaimplementuj metodę textFieldShouldReturn: w następujący sposób:

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

W twoim przykładzie brakuje tej linii:

confirmPasswordTextField.delegate = self

Jeśli zaimplementowałeś oczywiście delegata.

 37
Author: Stefan Salatic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-28 18:03:12

Próbowałem przetestować moje pola tekstowe w SignUpWindowView.swift, czyli gdzie tworzone są wszystkie pola tekstowe. Ale, ponieważ umieszczam SignUpWindowView w moim MainViewController jako subview, wszystkie moje UITextField "obsługa" musiała być wykonana w MainView, a nie jego subview.

Więc oto mój cały kod (w tej chwili) dla mojego MainViewController, który obsługuje przenoszenie mój SignUpWindowView w górę / w dół, gdy klawiatura jest pokazana / ukryta,a następnie przenosi się z jednego pola do drugiego. Gdy użytkownik znajduje się w ostatnim polu tekstowym (którego klawiatura Następny przycisk jest teraz ustawiony na gotowe w subview), klawiatura odsuwa się, a użytkownik może następnie przesłać formularz za pomocą przycisku rejestracji.

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
Author: Amy Plant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-29 00:39:40

Używanie znaczników ułatwia sprawę. Przypisz znaczniki w kolejności rosnącej do wszystkich pól tekstowych używanych na ekranie.


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
}
 5
Author: PhaniBhushan kolla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-15 19:06:07

Łączysz DidEndOnExit(napisałem to z pamięci, więc może nie nazywa się to dokładnie, ale podobnie) UIControl Zdarzenie za pomocą @IBAction i w tym func używasz textF.resignFirstResponder() lub .becomeFirstResponder()


EDIT

UITextField jest podklasą UIControl i aby programowo dodać nowe zdarzenie należy użyć metody addTarget (). Ex:

func a(sender: AnyObject) {}

textField.addTarget(self, action: "a:", forControlEvents: .EditingDidEndOnExit)

UIControl docs

 1
Author: Arbitur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-28 19:43:52