Reputation: 23
Im trying to jump from one Textfield in a Cell, to the TextField in the next Cell of a CollectionView, by hitting the enter button, but I can't get it to work.
I have assigned an individual Tag to all the Textfields when the cells get create, by giving every Textfield the corresponding indexPath as Tag:
// make a cell for each cell index path
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// get a reference to our storyboard cell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! MyCollectionViewCell
// Use the outlet in our custom class to get a reference to the UILabel in the cell
cell.myLabel.text = self.items[indexPath.item]
cell.myTextField.tag = indexPath.row
cell.backgroundColor = UIColor(red:0.94, green:0.94, blue:0.94, alpha:1.0) // make cell more visible in our example project
// Change shape of cells
cell.layer.cornerRadius = 8
return cell
}
Now my intention was, to use the code below to get to the next Textfield, if there is one:
extension ViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Try to find next responder
print(textField.tag) // Test if chosen textfield has individual tag
if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField {
nextField.becomeFirstResponder()
} else {
// Not found, so remove keyboard.
textField.resignFirstResponder()
}
// Do not add a line break
return false
}
}
But whenever I click on the enter button, nextField is always nil, the else case will be executed and the keyboard goes away. My guess is, that nextField looks in the wrong place for other TextFields and thats the reason why it can't find them (There is one Textfield per Cell, but no TextFields in the ViewController directly).
Since Im pretty new to programming in general, I have no clue how to solve this problem.
Upvotes: 1
Views: 1765
Reputation: 76
if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField
In this code textField.superview is current cell.There is no view's tag equal textField.tag + 1.You should get next cell first,then get textFiled. Change your code like this
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Try to find next responder
print(textField.tag)
// Test if chosen textfield has individual tag
let nextCell = self.collectionView?.cellForItem(at: IndexPath.init(row: textField.tag + 1, section: 0))
if let nextField = nextCell.viewWithTag(textField.tag + 1) as? UITextField {
nextField.becomeFirstResponder()
} else {
// Not found, so remove keyboard.
textField.resignFirstResponder()
}
// Do not add a line break
return false
}
Upvotes: 2
Reputation: 318794
You are incorrectly assuming that the collection view is the super view of each text field. This isn't true. The text field's superview is actually the collection view cell's contentView
which in turn is some deep down subview of the collection view cell which is ultimately a subview of the collection view.
You also have an issue of trying to move to the next text field when the next text field isn't even visible.
You need to take a different approach. At a high level you need to do the following in your textFieldShouldReturn
method:
For step 1 you need to convert a point in the text field to a point in the collection view. Then use the collection view method indexPathForItem(at:)
to get the index path of the cell for the current text field.
For step 2 it depends on your layout. Simply increment the item
. Possibly increment the section
. Be sure to check if you are at the last cell.
For step 3, scroll the collection view as needed.
For step 4, use the cellForItem(at:)
collection view method passing in the new index path from step 2. This gives you the next cell. Then access its text field and make it the first responder.
Upvotes: 1