Reputation: 19
I am creating a signup screen.
There are four UITextField, which is the ID, password, password check, name,
I am @Iboutlet var signupTextFields: [UITextField]!
I connected it. After that, I want to make an ID, password validation.
First, I divided ViewController and UItextFieldDelegate.
class SignUpViewController: UIViewController {
@IBOutlet var signUpTextFields: [UITextField]! {
didSet {
signUpTextFields.forEach { textField in
textField.delegate = textFieldDelegate
textField.returnKeyType = .next
}
}
}
@IBOutlet weak var nextButton: UIButton!
private lazy var textFieldDelegate = TextFieldDelegate(self)
override func viewDidLoad() {
super.viewDidLoad()
signUpTextFields.first?.becomeFirstResponder()
}
@IBAction func nextButtonTapped(_ sender: UIButton) {
}
}
class TextFieldDelegate: NSObject, UITextFieldDelegate {
private weak var signUpViewController: SignUpViewController?
init(_ signUpViewController: SignUpViewController) {
self.signUpViewController = signUpViewController
}
func textFieldDidBeginEditing(_ textField: UITextField) {
textField.layer.borderWidth = 1
textField.layer.borderColor = UIColor.systemBlue.cgColor
}
func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
textField.layer.borderColor = UIColor.black.cgColor
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
The problem when using the functions provided by Delegate is that the example code is to identify UITextField using if-else, such as
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == idTextField {
//code
} else if textField == passwordTextField {
//code
}
}
I was not this way, but I thought I wanted to abstract the uitextfield a little more to use the Factory method or polymorphism.
Is there a way to identify a UITextField Collection without using if-Else?
Upvotes: 0
Views: 92
Reputation: 534977
Using the same delegate for all of the text fields was bad design if your intention was to behave differently in the delegate methods. If it’s too late to change that, I would recommend an array of closures corresponding to the array of text fields. That way, calling the right closure is a one-liner based on firstIndex(of:)
.
Upvotes: 0
Reputation: 83
I'd recommend - Tag + Enum. (tag field is the norm to identify a view instance from Storyboard / Xib in the cases where you don't have individual IBOutlets)
Set "tag" in the Storyboard - ensure they are unique. (simple index oughta be enough -- 0, 1, 2 .. etc.)
Create an enum inside the view controller.
enum TextField {
case name = 0
case password = 1
} & so on (explicitly declare the tag values in the enum)
Use Switch instead of if-else for identification.
switch textField.tag { case .name: case .password: }
This should suffice for your case (since you are just going through an example code). But it's good that you are interested in clean code -- I'd recommend creating the TextFields programmatically & using the enum to set the .tag field.
Upvotes: 0