Получить индексную таблицу UITextField в UITableViewCell с помощью Swift

Итак, я создаю приложение диспетчера подробных представлений, в котором представлена ​​таблица с двухчастной ячейкой: меткой и текстовым полем.

Я пытаюсь получить значение текстового поля и добавить его в массив. Я попытался использовать технику "textField.superview.superview", но это не сработало.

func textFieldDidEndEditing(textField: UITextField!){
    var cell: UITableViewCell = textField.superview.superview
    var table: UITableView = cell.superview.superview
    let textFieldIndexPath = table.indexPathForCell(cell)
}

Xcode не удается создать и представляет, что "UIView не конвертируется в UITableViewCell" и "to UITableView". Ссылающаяся таблица имеет два раздела: четыре и две строки соответственно.

Спасибо заранее.

EDIT: добавлено ".superview" во второй строке функции.

Ответ 1

Вы хотите использовать первую и вторую строки в своей функции, например:

func textFieldDidEndEditing(textField: UITextField!){
    var cell: UITableViewCell = textField.superview.superview as UITableViewCell
    var table: UITableView = cell.superview as UITableView
    let textFieldIndexPath = table.indexPathForCell(cell)
}

superiew возвращает UIView, поэтому вам нужно отдать его в ожидаемый тип просмотра.

Ответ 2

В то время как принятый в настоящее время ответ может работать, он предполагает определенную иерархию представлений, которая не является надежным подходом, поскольку она подвержена изменениям.

Чтобы перейти к indexPath из UITextField внутри ячейки, гораздо лучше пойти со следующим:

func textFieldDidEndEditing(textField: UITextField!){
    let pointInTable = textField.convertPoint(textField.bounds.origin, toView: self.tableView)
    let textFieldIndexPath = self.tableView.indexPathForRowAtPoint(pointInTable)
}

Это будет продолжать работать независимо от возможных изменений в иерархии представлений.

Ответ 3

Использование супервизора и типизации не является предпочтительным aaproach. Лучшей практикой является использование шаблона делегата. Если у вас есть textField в DemoTableViewCell, который вы используете в DemoTableViewController, создайте протокол DemoTableViewCellDelegate и назначьте делегат DemoTableViewCell DemoTableViewController, чтобы диспетчер просмотра уведомлялся, когда eiditing заканчивается в текстовом поле.

protocol DemoTableViewCellDelegate: class {
  func didEndEditing(onCell cell: DemoTableViewCell)
}

class DemoTableViewCell: UITableViewCell {
  @IBOutlet var textField: UITextField!

  weak var delegate: DemoTableViewCellDelegate?

  override func awakeFromNib() {
    super.awakeFromNib()
    textField.delegate = self
  }
}

extension DemoTableViewCell: UITextFieldDelegate {
  func textFieldDidEndEditing(_ textField: UITextField) {
    delegate.didEndEditing(onCell: self)
  }
}

class DemoTableViewController: UITableViewController {

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: DemoTableViewCell.self, for: indexPath)
    cell.delegate = self
    return cell
  }

}

extension DemoTableViewController: DemoTableViewCellDelegate {
  func didEndEditing(onCell cell: DemoTableViewCell) {
    //Indexpath for the cell in which editing have ended.
    //Now do whatever you want to do with the text and indexpath.
    let indexPath = tableView.indexPath(for: cell)
    let text = cell.textField.text
  }
}