Swift:跳转到 CollectionView 中的下一个文本字段

Posted

技术标签:

【中文标题】Swift:跳转到 CollectionView 中的下一个文本字段【英文标题】:Swift: Jump to next Textfield in a CollectionView 【发布时间】:2017-03-09 15:05:26 【问题描述】:

我试图通过按 Enter 按钮从 Cell 中的一个 Textfield 跳转到 CollectionView 的下一个 Cell 中的 TextField,但我无法让它工作。

我在创建单元格时为所有文本字段分配了一个单独的标签,方法是为每个文本字段提供相应的 indexPath 作为标签:

// 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

现在我的意图是,使用下面的代码进入下一个文本字段,如果有的话:

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

但是每当我点击回车按钮时,nextField 总是为零,否则将执行 else 情况并且键盘消失。 我的猜测是,nextField 在错误的位置查找其他 TextField,这就是它找不到它们的原因(每个 Cell 有一个 Textfield,但 ViewController 中直接没有 TextField)。

由于我对编程很陌生,所以我不知道如何解决这个问题。

【问题讨论】:

您似乎错误地假设文本字段的超级视图是集合视图。 这正是我的想法。 TextField 的超类是什么,甚至更好:我怎样才能知道超类是什么? 【参考方案1】:
if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField

在此代码中 textField.superview 是当前单元格。没有视图的标签等于 textField.tag + 1。您应该先获取下一个单元格,然后获取 textFiled。 像这样更改您的代码

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

【讨论】:

在这种情况下如何进入下一个单元格? (对不起这个问题,我没有编程背景,我只是想学习 Swift) textField.superview 不是当前单元格。这是当前单元格的子视图。 请记住,如果可以添加、删除或移动任何单元格,此代码将失败。使用标签来表示索引路径通常是个坏主意。【参考方案2】:

您错误地假设集合视图是每个文本字段的超级视图。这不是真的。文本字段的超级视图实际上是集合视图单元格的contentView,而这又是集合视图单元格的一些深层子视图,最终是集合视图的子视图。

当下一个文本字段甚至不可见时,您还会尝试移动到下一个文本字段。

您需要采取不同的方法。概括地说,您需要在 textFieldShouldReturn 方法中执行以下操作:

    确定文本字段单元格的索引路径。 计算下一个索引路径。 确保下一个索引路径的单元格在视图中。 使下一个单元格的文本字段成为第一响应者。

对于第 1 步,您需要将文本字段中的一个点转换为集合视图中的一个点。然后使用集合视图方法indexPathForItem(at:)获取当前文本字段的单元格的索引路径。

第 2 步取决于您的布局。只需增加item。可能增加section。请务必检查您是否在最后一个单元格。

对于第 3 步,根据需要滚动集合视图。

对于第 4 步,使用 cellForItem(at:) 集合视图方法传入第 2 步中的新索引路径。这将为您提供下一个单元格。然后访问其文本字段并使其成为第一响应者。

【讨论】:

以上是关于Swift:跳转到 CollectionView 中的下一个文本字段的主要内容,如果未能解决你的问题,请参考以下文章

IOS Swift - UIWebView 跳转到锚标签

Xcode 从 viewcontroller.swift 跳转到 storyboard

在 Swift 中使用 UIPageViewController 直接跳转到特定页面

使用 Swift 2.0 解析并跳转到 JSON 文件中的下一个块

Swift 跳转到系统设置指定页面

使用 Swift 在 iOS 媒体播放器上跳转到索引号项目...