Reputation: 3755
I have a screen called OTP. In that, I have set dynamic textfields using collectionview cell. I am able to fetch the user enters text from that textfields using the tag. But, I have an issue like, All four textfields filled then only I have to enable the Send button in the UI until that Send button would be disabled.
I am able to get text from textfields based on the textfield tag. But, How to detect wether all textfields filled or not from collectionview cell?
Any suggestions?
My code is below:
class OTPViewController: UITableViewController, UICollectionViewDelegate, UICollectionViewDataSource, UITextFieldDelegate {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return otpTextCount //either 4 or 6 number comes from server array
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! OTPCollectionViewCell
cell.otpTextField.tag = indexPath.row
cell.otpTextField.delegate = self
return cell
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
textField.text = textField.text?.replacingOccurrences(of: " ", with: "")
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
var cell: OTPCollectionViewCell?
cell = textField.superview?.superview as? OTPCollectionViewCell
// print(cell?.otpTextField.text as! String)
// print(cell?.otpTextField.tag)
}
Upvotes: 1
Views: 312
Reputation: 3755
I have found following way and it worked fine.
private var arrayOfCells: [OTPCollectionViewCell] = []
var insertedValues = [String]()
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! OTPCollectionViewCell
cell.otpTextField.tag = indexPath.row
cell.otpTextField.delegate = self
arrayOfCells += [cell]
return cell
}
func textFieldDidEndEditing(_ textField: UITextField) {
if insertedValues.count > 0 {
insertedValues.removeAll()
}
for i in 0..<arrayOfCells.count {
if let textfieldText = arrayOfCells[i].otpTextField.text, textfieldText != "" {
insertedValues.append(textfieldText)
if insertedValues.count == 4 //otpTextCount{
nextButton.isUserInteractionEnabled = true
}
} else {
nextButton.isUserInteractionEnabled = false
}
}
}
Upvotes: 0
Reputation: 455
I would recommend you to store text that were inserted into UITextFields into some sort of dictionary [Int: String]
where key is the tag of cell. Then if the dictionary contains all necessary tags we can enable the button.
The example follows. I personally would recommend storing states in something like a ViewModel
and moving that logic there. But this is a sample code that I did not compile, its purpose it to simply show the idea.
class OTPViewController: UITableViewController, UICollectionViewDelegate, UICollectionViewDataSource, UITextFieldDelegate {
var insertedValues = [Int: String]()
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return otpTextCount //either 4 or 6 number comes from server array
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! OTPCollectionViewCell
cell.otpTextField.tag = indexPath.row
cell.otpTextField.delegate = self
return cell
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
textField.text = textField.text?.replacingOccurrences(of: " ", with: "")
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
guard let cell = textField.superview?.superview as? OTPCollectionViewCell else {
assertionFailure("Orphan textField did end editing. No cell found")
return
}
if textField.text == "" {
insertedValues[cell.tag] = nil
} else {
insertedValues[cell.tag] = textField.text
}
theButton.isEnabled = areAllFieldsFilled()
// print(cell?.otpTextField.text as! String)
// print(cell?.otpTextField.tag)
}
func areAllFieldsFilled() -> Bool {
for n in 0..<otpTextCount {
if !insertedValues.keys.contains(n) {
return false
}
}
return true
}
Upvotes: 1