Switching Between Text Fields on Pressing Return Key in Swift

How UITextField move to next TextField When Click on Return Key in Keyboard

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

if textField == txtFldSponsorID {
txtFldFullName.becomeFirstResponder()
} else if textField == txtFldFullName {
txtFldEmail.becomeFirstResponder()
} else if textField == txtFldEmail {
txtFldMobile.becomeFirstResponder()
} else if textField == txtFldMobile {
txtFldAddress.becomeFirstResponder()
} else {
txtFldCity.resignFirstResponder()
}
return true
}

You can use this above UITextField Delegate method to jump to next UItextField.

Using Next as a Return Key

Make sure your text fields have their delegate set and implement the textFieldShouldReturn method. This is the method that is called when the user taps the return key (no matter what it looks like).

The method might look something like this:

func textFieldShouldReturn(textField: UITextField) -> Bool {
if textField == self.field1 {
self.field2.becomeFirstResponder()
}

return true
}

The actual logic in here might vary. There are numerous approaches, and I'd definitely advise against a massive if/else chain if you have lots of text fields, but the gist here is to determine what view is currently active in order to determine what view should become active. Once you've determined which view should become active, call that view's becomeFirstResponder method.


For some code cleanliness, you might consider a UITextField extension that looks something like this:

private var kAssociationKeyNextField: UInt8 = 0

extension UITextField {
var nextField: UITextField? {
get {
return objc_getAssociatedObject(self, &kAssociationKeyNextField) as? UITextField
}
set(newField) {
objc_setAssociatedObject(self, &kAssociationKeyNextField, newField, .OBJC_ASSOCIATION_RETAIN)
}
}
}

And then change our textFieldShouldReturn method to look like this:

func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.nextField?.becomeFirstResponder()
return true
}

Once you've done this, it should simply be a matter of setting each text field's new nextField property in viewDidLoad:

self.field1.nextField = self.field2
self.field2.nextField = self.field3
self.field3.nextField = self.field4
self.field4.nextField = self.field1

Although if we really wanted, we could prefix the property with @IBOutlet, and that would allow us to hook up our "nextField" property right in interface builder.

Change the extension to look like this:

private var kAssociationKeyNextField: UInt8 = 0

extension UITextField {
@IBOutlet var nextField: UITextField? {
get {
return objc_getAssociatedObject(self, &kAssociationKeyNextField) as? UITextField
}
set(newField) {
objc_setAssociatedObject(self, &kAssociationKeyNextField, newField, .OBJC_ASSOCIATION_RETAIN)
}
}
}

And now hook up the nextField property in interface builder:

enter image description here

(Set up your delegate while you're here too.)


And of course, if the nextField property returns nil, the keyboard just hides.

How to navigate through textfields (Next / Done Buttons)

In Cocoa for Mac OS X, you have the next responder chain, where you can ask the text field what control should have focus next. This is what makes tabbing between text fields work. But since iOS devices do not have a keyboard, only touch, this concept has not survived the transition to Cocoa Touch.

This can be easily done anyway, with two assumptions:

  1. All "tabbable" UITextFields are on the same parent view.
  2. Their "tab-order" is defined by the tag property.

Assuming this you can override textFieldShouldReturn: as this:

-(BOOL)textFieldShouldReturn:(UITextField*)textField
{
NSInteger nextTag = textField.tag + 1;
// Try to find next responder
UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];
if (nextResponder) {
// Found next responder, so set it.
[nextResponder becomeFirstResponder];
} else {
// Not found, so remove keyboard.
[textField resignFirstResponder];
}
return NO; // We do not want UITextField to insert line-breaks.
}

Add some more code, and the assumptions can be ignored as well.

Swift 4.0

 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let nextTag = textField.tag + 1
// Try to find next responder
let nextResponder = textField.superview?.viewWithTag(nextTag) as UIResponder!

if nextResponder != nil {
// Found next responder, so set it
nextResponder?.becomeFirstResponder()
} else {
// Not found, so remove keyboard
textField.resignFirstResponder()
}

return false
}

If the superview of the text field will be a UITableViewCell then next responder will be

let nextResponder = textField.superview?.superview?.superview?.viewWithTag(nextTag) as UIResponder!

Change 'Return' button function to 'Done' in swift in UITextView

You can set the return key type of the text field:

textField.returnKeyType = UIReturnKeyType.done

Update
You can definitely use the same approach to set the return key to "Done", as mentioned above. However, UITextView doesn't provide a callback when user hits the return key. As a workaround, you can try to handle the textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) delegate call, and dismiss the keyboard when you detect the input of a new line character:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if (text == "\n") {
textView.resignFirstResponder()
}
return true
}

Switch between UITextFields when return button is pressed

To solve the private problem

if let nextField = self.view.viewWithTag(textField.tag + 1) as? UITextField 

but it's problem is in performance viewWithTag recursively searches in subviews

How do I get the return key to perform the same action as a button press in Swift?

Make sure your class extends the UITextFieldDelegate protocol

SomeViewControllerClass : UIViewController, UITextFieldDelegate

You can perform action as follows:

override func viewDidLoad() {
super.viewDidLoad()

self.textField.delegate = self
}

func textFieldShouldReturn(textField: UITextField) -> Bool {

//textField code

textField.resignFirstResponder() //if desired
performAction()
return true
}

func performAction() {
//action events
}


Related Topics



Leave a reply



Submit