focusing a text field in swift
I have 4 textfields on a register screen and i have it set up so that when the user presses next on each text field, the next text field is focused. Code below:
func textFieldShouldReturn(textField: UITextField) -> Bool {
if (textField == self.fNameField) {
textField.resignFirstResponder()
self.sNameField.becomeFirstResponder()
}
else if (textField == self.sNameField) {
self.emailField.becomeFirstResponder()
} else if (textField == self.emailField) {
self.passwordField.becomeFirstResponder()
}
else {
var thereWereErrors = checkForErrors()
if !thereWereErrors
{
//conditionally segue to next screen
}
}
return true
}
On the return of the final text field, I am calling a check for errors function (below). Within that if there is an issue with any field I want to focus that text field so the user can easily correct it. What is happening is that the text field with the error is focusing (as instructed by the checkForErrors functions)for a second but then the focus is switching back to the password text field. I also tried adding in self.passwordField.resignFirstResponder()
into the last else of the above function and that makes the password field lose focus but then the text field with the issue encountered is not gaining focus at all (not even for a second as before) How can I fix this?
func checkForErrors() -> Bool
{
var errors = false
let title = "Error"
var message = ""
if fNameField.text.isEmpty {
errors = true
message += "First name empty"
alertWithTitle(title, message: message, ViewController: self)
self.fNameField.becomeFirstResponder()
}
else if sNameField.text.isEmpty
{
errors = true
message += "Surname empty"
alertWithTitle(title, message: message, ViewController: self)
self.sNameField.becomeFirstResponder()
}
else if emailField.text.isEmpty
{
errors = true
message += "Email empty"
alertWithTitle(title, message: message, ViewController: self)
self.emailField.becomeFirstResponder()
}
else if !isValidEmail(emailField.text)
{
errors = true
message += "Invalid Email Address"
alertWithTitle(title, message: message, ViewController: self)
self.emailField.becomeFirstResponder()
}
else if passwordField.text.isEmpty
{
errors = true
message += "Password empty"
alertWithTitle(title, message: message, ViewController: self)
self.passwordField.becomeFirstResponder()
}
else if count(passwordField.text.utf16)<8
{
errors = true
message += "Password must be at least 8 characters"
alertWithTitle(title, message: message, ViewController: self)
self.passwordField.becomeFirstResponder()
}
return errors
}
Note I have included the textField delegate.
alert with title function as requested:
func alertWithTitle(title: String!, #message: String, #ViewController: UIViewController) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let action = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alert.addAction(action)
ViewController.presentViewController(alert, animated: true, completion: nil)
}
theTextFieldYouWant.becomeFirstResponder()
This works for me:
import UIKit
class ViewController:UIViewController, UITextFieldDelegate {
@IBOutlet weak var fNameField: UITextField!
@IBOutlet weak var sNameField: UITextField!
@IBOutlet weak var emailField: UITextField!
@IBOutlet weak var passwordField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
fNameField.delegate = self
sNameField.delegate = self
emailField.delegate = self
passwordField.delegate = self
}
func isValidEmail (test:String) ->Bool{
// your email validation here...
return true
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
if (textField == self.fNameField) {
self.sNameField.becomeFirstResponder()
}
else if (textField == self.sNameField) {
self.emailField.becomeFirstResponder()
} else if (textField == self.emailField) {
self.passwordField.becomeFirstResponder()
}
else{
var thereWereErrors = checkForErrors()
if !thereWereErrors
{
//conditionally segue to next screen
}
}
return true
}
func checkForErrors() -> Bool
{
var errors = false
let title = "Error"
var message = ""
if fNameField.text.isEmpty {
errors = true
message += "First name empty"
alertWithTitle(title, message: message, ViewController: self, toFocus:self.fNameField)
}
else if sNameField.text.isEmpty
{
errors = true
message += "Surname empty"
alertWithTitle(title, message: message, ViewController: self, toFocus:self.sNameField)
self.sNameField.becomeFirstResponder()
}
else if emailField.text.isEmpty
{
errors = true
message += "Email empty"
alertWithTitle(title, message: message, ViewController: self, toFocus:self.emailField)
}
else if !isValidEmail(emailField.text)
{
errors = true
message += "Invalid Email Address"
alertWithTitle(title, message: message, ViewController: self, toFocus:self.emailField)
}
else if passwordField.text.isEmpty
{
errors = true
message += "Password empty"
alertWithTitle(title, message: message, ViewController: self, toFocus:passwordField)
}
else if count(passwordField.text.utf16)<8
{
errors = true
message += "Password must be at least 8 characters"
alertWithTitle(title, message: message, ViewController: self, toFocus:self.passwordField)
}
return errors
}
func alertWithTitle(title: String!, message: String, ViewController: UIViewController, toFocus:UITextField) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let action = UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel,handler: {_ in
toFocus.becomeFirstResponder()
});
alert.addAction(action)
ViewController.presentViewController(alert, animated: true, completion:nil)
}
}