ios 使用带有 textFieldShouldReturn 的 Swift 的下一步/完成按钮

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29925851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:49:32  来源:igfitidea点击:

Next/Done button using Swift with textFieldShouldReturn

iosswiftxcode6subviewuitextfielddelegate

提问by Amy Plant

I have a MainView that adds a subview (signUpWindow) when a sign up button is pressed.

我有一个 MainView,它在按下注册按钮时添加一个子视图 (signUpWindow)。

In my signUpWindow subview (SignUpWindowView.swift), I set up each field with a function, as an example:

在我的 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)
    }

I have the keyboard moving the signUpWindow up and down when it appears and disappears in the MainView.

当 signUpWindow 在 MainView 中出现和消失时,我让键盘上下移动它。

SignUpWindowViewimplements the UITextFieldDelegate

SignUpWindowView实施 UITextFieldDelegate

My problem is that I am trying to configure the Next/Done button on the keyboard and am not sure which view (MainViewor SignUpWindowView) to add the textFieldShouldReturnfunction. I have tried both, but can't even get a printlnto fire to test to see if the function is even being executed. Once I get the textFieldShouldReturnto fire, I am confident I can execute the necessary code to get the Next/Done buttons to do what I want, and will post the final solution to include the Next/Done function.

我的问题是我正在尝试配置键盘上的 Next/Done 按钮,但不确定要添加该功能的视图(MainViewSignUpWindowViewtextFieldShouldReturn。我已经尝试了这两种方法,但甚至无法println测试以查看该函数是否正在执行。一旦我textFieldShouldReturn触发,我相信我可以执行必要的代码来让 Next/Done 按钮执行我想要的操作,并将发布最终解决方案以包含 Next/Done 功能。

UPDATED to include an abbreviated version of SignUpWindowView.swift

更新以包含 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()
}

采纳答案by Amy Plant

I was attempting to test my textfields in the SignUpWindowView.swift, which is where all of the textFields are created. But, since I place SignUpWindowView into my MainViewController as a subview, all of my UITextField "handling" needed to be done in the MainView and NOT its subview.

我试图在 SignUpWindowView.swift 中测试我的文本字段,这是创建所有文本字段的地方。但是,由于我将 SignUpWindowView 作为子视图放入 MainViewController 中,因此所有 UITextField “处理”都需要在 MainView 中完成,而不是在其子视图中完成。

So here is my entire code (at the moment) for my MainViewController, which handles moving my SignUpWindowView up/down when the keyboard is shown/hidden and then moves from one field to the next. When the user is in the last text field (whose keyboard Next button is now set to Done in the subview) the keyboard tucks away and the user can then submit the form with a signup button.

所以这是我的 MainViewController 的完整代码(目前),它处理在显示/隐藏键盘时向上/向下移动我的 SignUpWindowView,然后从一个字段移动到下一个字段。当用户位于最后一个文本字段时(其键盘 Next 按钮现在在子视图中设置为 Done),键盘会收起,然后用户可以使用注册按钮提交表单。

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

回答by Stefan Salatic

You need to implement UITextFieldDelegatein your class and set that object as the delegate for the UITextField. Then implement the method textFieldShouldReturn:like this:

您需要UITextFieldDelegate在您的类中实现并将该对象设置为UITextField. 然后实现这样的方法textFieldShouldReturn:

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

In your example you are missing this line:

在您的示例中,您缺少这一行:

confirmPasswordTextField.delegate = self

If you have implemented the delegate of course.

当然,如果您已经实现了委托。

回答by PhaniBhushan kolla

Using tags makes it easier. Assign tags in ascending order to all the text fields you are using on your screen.

使用标签更容易。按升序为您在屏幕上使用的所有文本字段分配标签。



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
}

回答by Arbitur

You connect the DidEndOnExit(I wrote this from memory so maybe its not called this exactly but similar) UIControlevent using an @IBActionand in that func you use textF.resignFirstResponder()or .becomeFirstResponder()

您连接DidEndOnExit(我是从内存中写的,所以它可能不完全称为这个而是相似的)UIControl事件使用@IBAction和 在您使用的那个 func 中textF.resignFirstResponder().becomeFirstResponder()



EDIT

编辑

UITextField is subclass of UIControl and to programatically add a new event you use the addTarget() method. Ex:

UITextField 是 UIControl 的子类,可以使用 addTarget() 方法以编程方式添加新事件。前任:

func a(sender: AnyObject) {}

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

UIControl docs

UIControl 文档