Бутон „Напред/Готово“ с помощта на Swift с textFieldShouldReturn

Имам MainView, който добавя подизглед (signUpWindow), когато се натисне бутон за регистрация.

В моя подизглед на signUpWindow (SignUpWindowView.swift) настройвам всяко поле с функция, като пример:

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

Клавиатурата движи signUpWindow нагоре и надолу, когато се появява и изчезва в MainView.

SignUpWindowView прилага UITextFieldDelegate

Проблемът ми е, че се опитвам да конфигурирам бутона Next/Done на клавиатурата и не съм сигурен кой изглед (MainView или SignUpWindowView) да добавя функцията textFieldShouldReturn. Опитах и ​​двете, но дори не мога да накарам println да се задейства, за да тествам дали функцията изобщо се изпълнява. След като накарам textFieldShouldReturn да се задейства, уверен съм, че мога да изпълня необходимия код, за да накарам бутоните Next/Done да правят това, което искам, и ще публикувам окончателното решение за включване на функцията Next/Done.

АКТУАЛИЗИРАН за включване на съкратена версия на 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()
}

person Amy Plant    schedule 28.04.2015    source източник
comment
какво задавате да бъде делегат на текстовите полета?   -  person André Slotta    schedule 28.04.2015
comment
confirmPasswordTextField.delegate=self   -  person Amy Plant    schedule 28.04.2015


Отговори (4)


Трябва да внедрите UITextFieldDelegate във вашия клас и да зададете този обект като делегат за UITextField. След това внедрите метода textFieldShouldReturn: по този начин:

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

Във вашия пример ви липсва този ред:

confirmPasswordTextField.delegate = self

Ако сте внедрили делегата, разбира се.

person Stefan Salatic    schedule 28.04.2015
comment
И textFieldShouldReturn получава ли извикване? - person Stefan Salatic; 28.04.2015
comment
Така че имам някои проблеми с отговора, за да покажа кода по начина, по който искам да се показва. Зададох делегата, малко по-рано. Приложих UITextFieldDelegate както в MainView, така и в SubView. Написах кода за textFieldShouldReturn, само с println в момента, за да видя дали се извиква или в MainView, или в subView ... нито един не го извиква. - person Amy Plant; 28.04.2015
comment
Трябва да направите всичко, което Стефан е написал в SignUpWindowView.swift, стига да създавате там текстово поле и да задавате self като делегат на текстово поле - person Ossir; 28.04.2015
comment
Редактирах оригиналната си публикация, за да включва съкратена версия на SignUpWindowView.swift 1) показва внедрения делегат 2) показва textfield.delegate=self и 3) показва функцията textFieldShould return, но все още не получавам textFieldShouldReturn за получаване извиква се, когато докосна бутона за следващ или готов :( - person Amy Plant; 29.04.2015
comment
Трябва да преместите textFieldShouldReturn извън drawRect. По този начин той е вътре във функция, а не в клас. Протоколът няма да го разпознае и функцията няма да бъде извикана. - person Stefan Salatic; 29.04.2015
comment
За Swift 3 трябва да има '_' точно преди параметрите във функцията. - person wasimsandhu; 11.05.2017

Опитвах се да тествам моите текстови полета в SignUpWindowView.swift, където се създават всички текстови полета. Но тъй като поставям SignUpWindowView в моя MainViewController като подизглед, цялата ми "обработка" на UITextField трябваше да се извърши в MainView, а НЕ в неговия подизглед.

Така че тук е целият ми код (в момента) за моя MainViewController, който управлява преместването на моя SignUpWindowView нагоре/надолу, когато клавиатурата е показана/скрита и след това се премества от едно поле към следващото. Когато потребителят е в последното текстово поле (чийто бутон на клавиатурата „Напред“ вече е зададен на „Готово“ в подизгледа), клавиатурата се прибира и след това потребителят може да изпрати формуляра с бутон за регистрация.

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)
    }
}
person Amy Plant    schedule 29.04.2015
comment
Ейми, пропускаш извикване на super.viewWillDisappear(), което вероятно искаш там (но иначе добра работа). - person gemmakbarlow; 11.05.2015

Използването на етикети го прави по-лесно. Задайте етикети във възходящ ред на всички текстови полета, които използвате на екрана си.


func textFieldShouldReturn(_ textField: UITextField) -> Bool {

    let textTag = textField.tag+1
    if let nextResponder = textField.superview?.viewWithTag(textTag) as UIResponder
    {
        //textField.resignFirstResponder()
        nextResponder.becomeFirstResponder()
    }
    else {
        // stop editing on pressing the done button on the last text field.

        self.view.endEditing(true)
    }
    return true
}
person PhaniBhushan kolla    schedule 29.12.2017
comment
не работи за мен nextResponder нула през цялото време след self.view.superview?.viewWithTag(textTag) като UIResponder? смени това е работа за мен - person Harshil Kotecha; 08.05.2018

Свързвате DidEndOnExit(написах това по памет, така че може би не се нарича точно така, но подобно) UIControl събитие с помощта на @IBAction и в тази функция използвате textF.resignFirstResponder() или .becomeFirstResponder()


РЕДАКТИРАНЕ

UITextField е подклас на UIControl и за програмно добавяне на ново събитие използвате метода addTarget(). Пример:

func a(sender: AnyObject) {}

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

UIControl документи

person Arbitur    schedule 28.04.2015
comment
Как да постигна това програмно в Swift. Не използвам сценарий за добавяне на подизглед. SignUpWindowView.swift е клас, който след това се добавя към MainView чрез бутон за регистрация (който е в сценария), който изпълнява функция, която добавя подизгледа signUpWindow. Има ли логика в това? Използвам бита .becomeFirstResponder ... просто не мога да го накарам да разпознае функцията textFieldShouldReturn. - person Amy Plant; 28.04.2015