【问题标题】:UIView extension to get UITableViewCell?UIView 扩展获取 UITableViewCell?
【发布时间】:2017-02-18 06:00:14
【问题描述】:

如果 UIView 的特定实例确实是 UITableViewCell 的子视图,我正在制作一个 UIView 扩展,它返回一个可能的 UITableViewCell。

这个想法是稍后我可以将 UITableViewCell 引用传递给 UITableView 的 indexPath(for:) 方法来获取单元格的索引路径。

因此,如果我的表格视图单元格包含 UITextField,我能够在调用 UITextFieldDelegate 的 textFieldDidEndEditing(_ textField: UITextField) 方法时识别该文本字段来自哪个单元格。

到目前为止,这是我想出的:

extension UIView {
    var tableViewCell: UITableViewCell? {
        get {
            var view = self
            while let superview = view.superview {
                if let tableViewCell = superview as? UITableViewCell {
                    return tableViewCell
                }
                view = superview
            }
            return nil
        }
    }
}

我有两个问题:

  1. 由于我是使用 Swift 编程的新手,请问是否有更好的(Swiftier?)方法来编写这个?

  2. 这是识别包含正在编辑的 UITextField 的 UITableViewCell 的索引路径的好方法吗?有没有更好的办法?

我实际上是 Swift 和 Stack Overflow 的新手,如果我做错了什么,非常抱歉(请多多原谅),我希望得到您的指导。谢谢。

【问题讨论】:

    标签: ios swift uitableview uiview swift3


    【解决方案1】:

    最简洁的方法是简单地标记您的单元格文本字段。

    例如,您也可以使用indexPath.row 进行标记。

    然后在UITextFieldDelegate 方法textFieldDidBeginEditing(_:) 中只需检查begins editing 的textField 的标签,您就可以简单地从中创建一个NSIndexPath。

    但是,如果您在不同的部分中有多个部分和 UITextField,则需要部分和行才能使 NSIndexPath 正确。

    根据您在 tableView 中有多少 textFields,解决方案可能是创建一个 NSDictionary 来保留对部分和行的引用。

    【讨论】:

      【解决方案2】:

      这是一种计算 indexPath 的有趣方法,但更安全的方法可能是使用 textView 的委托方法并计算 tableViewCell 相对于 tableView 的 indexPath。

      class TableViewCell: UITableViewCell {
          @IBOutlet weak var textField: UITextField!
      }
      
      class ViewController: UIViewController {
          var indexPath: IndexPath?
          @IBOutlet weak var tableView: UITableView!
      
          func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
              guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? TableViewCell else { return UITableViewCell() }
              cell.textField.delegate = self
              return cell
          }
      }
      
      extension ViewController: UITextFieldDelegate {
          func textFieldDidBeginEditing(_ textField: UITextField) {
               let point = textField.convert(.zero, to: tableView)
               indexPath = tableView.indexPathForRow(at: point)
          }
      }
      

      【讨论】:

      • 更正您的答案。 1: 这是一个 UITextField 2: 他不能在 viewDidLoad 中设置委托,因为它包含在一个单元格中。 3: 需要在 cellForRowAtIndexPath: 方法中设置委托。 4 UIViewController 中不需要插座和属性,因为它包含在一个单元格中。 5:如果要设置delegate = self,则需要将UITextFieldDelegate添加到类中。
      【解决方案3】:

      这些是替代方案:
      1.根据点找到单元格。

      func textFieldDidEndEditing(_ sender: UITextField) {
              let tableViewTouchPoint:CGPoint = sender.convert(CGPointZero, to:self.tableView)
              let indexPath = self.tableView.indexPathForRow(at: tableViewTouchPoint)
      
          }
      

      为相同的Tableview创建一个扩展

      extension UITableView {
      
        func indexPathForView(_ view: UIView) -> IndexPath? {
          let tableViewTouchPoint:CGPoint = view.convert(CGPointZero, to:self)
              let indexPath = self.indexPathForRow(at: tableViewTouchPoint)
          return indexPath
        }
      }
      

      使用它

         let indexPath = self.tableView.indexPathForView(textField) 
      
      1. 基于子视图标签。在 CellForRowATIndex 中,将标签设置为等于 indexPath.row。然后,要取回 IndexPath 使用:

        让 index = sender.tag

        让 indePath = IndexPath(row: index, section: 0)

      【讨论】:

      • 这 2 个选项都是当前已回答的两个答案中的一个选项。
      • 好吧,格式化答案对我来说和你们发布的时候都需要时间。运气不好!
      • 不用担心,因为提供了多种选择而被赞成:)
      • 只是想提一下标签方法在“使用 beginUpdates 和 endUpdates 插入单元格”世界(核心数据 + 获取的结果控制器等)中不起作用(由于未在旧单元格上调用 CellForRowAtIndex 导致错误) )。点法仍然有效。
      • 是的,但是对于一般的简单tableview渲染,标签是最好和最简单的解决方案,是大多数人的首选。
      猜你喜欢
      • 2012-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-25
      • 2016-02-10
      相关资源
      最近更新 更多