I have a SignUp Form which includes a number of UITextfields
and UIButton
. I have set up UITextfield
delegates so that the when user starts editing on a UITextfield
and presses the return key it goes to the next UITextfield
.
DoB, ISD Code, Gender and Nationality are UIButtons
which have IBActions
, and rest of them are UITextfields
Is it possible to initiate a IBAction
of a UIButton
on pressing the return
key from a Textfield. So that the user can sequentially add the necessary data to the signup form.
What i have done so far ..
func textFieldShouldReturn(_ textField: UITextField) -> Bool{
if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField
{
nextField.becomeFirstResponder()
}
else {
// Not found, so remove keyboard.
signupScrollView .setContentOffset(CGPoint( x: 0, y: 0), animated: true)
textField.resignFirstResponder()
return true
}
// Do not add a line break
return false
}
func textFieldDidBeginEditing(_ textField: UITextField) {
signupScrollView .setContentOffset(CGPoint( x: 0, y: textField.center.y-200), animated: true)
}
Assuming your textField
s and button
s have a common sequence of tags, you can basically do something like the following:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let nextView = textField.superview?.viewWithTag(textField.tag + 1)
if let nextTextField = nextView as? UITextField {
//next view is a textField so make next textField first responder
nextTextField.becomeFirstResponder()
}
//just this extra case is required
else if let nextButton = nextView as? UIButton {
//next view is a button so call it's associated action
//(assuming your button's @IBAction is on the Touch Up Inside event)
nextButton.sendActions(for: .touchUpInside)
/*
a button's action will be performed so if you want to
perform the return action on the textField then either
return true/false. Decide that as per your requirement
*/
return true
}
else {
//...
}
//...
}
The above logic is enough to answer your question but works only when the user is on a textField
and has tapped on the keyboard's Return
button.
Now... the thing is that on the end of a button actions, if you want to continue to the next view; textField
or button
, you can either1 explicitly code to make the next view active.
Example:
ISD Code
is done you could make the mobile textField
as first responderGender
is done, you could call the button action for Nationality
We can modify the solution to handle textField
as well as button
s alike with a common helper function, that we will call goNext(from:)
to be implemented in textFieldShouldReturn(_:)
as well as after the button is to complete it's intended logic flow.
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let nextView = goNext(from: textField)
if let nextTextField = nextView as? UITextField {
//Next field was a textField so keyboard should stay
return false
}
textField.resignFirstResponder()
return true
}
@discardableResult func goNext(from sender: UIView) -> UIView? {
let nextView = sender.superview?.viewWithTag(sender.tag + 1)
print(nextView?.tag ?? "No view with tag \(sender.tag + 1)")
if let nextTextField = nextView as? UITextField {
nextTextField.becomeFirstResponder()
}
else if let nextButton = nextView as? UIButton {
nextButton.sendActions(for: .touchUpInside)
}
else {
print("Done")
signupScrollView.setContentOffset(CGPoint(x: 0, y: 0),
animated: true)
sender.resignFirstResponder()
}
return nextView
}
Now for the button part, you need to perform goNext(from: button)
whenever the associated button has completed it's logic.
Example:
User has successfully selected Date of Birth: You should then be calling
goNext(from: dobButton)