Подтвердить что ты не робот

Как обратиться к контроллеру с класса uitableviewcell в Swift

У меня есть следующее

  • ViewController
  • Tableview
  • CustomCell

Я использовал NIB (файл .xib) для ячейки, которая использует класс CustomCell. Этот пользовательский класс ячейки обрабатывает IBAction для некоторого касания кнопки соты. Я хотел бы ссылаться на ViewController и некоторые его переменные внутри него. Как я должен это делать (доступ к ViewController)?

Спасибо!

4b9b3361

Ответ 1

Я бы не стал создавать такую зависимость между ячейкой и контроллером представления - это делает архитектуру более сложной и ячейку нельзя использовать повторно.

Я предлагаю вам использовать шаблон делегирования, который может показаться немного сложным - хотя вы уже используете (UITableViewDelegate - типичный пример):

  • создайте протокол MyCellProtocol с одним методом didTapCell, принимая UITableViewCell и/или некоторые пользовательские данные, которые вы хотите передать в контроллер представления
  • создать открытое свойство делегата в вашей пользовательской ячейке: weak var cellDelegate: MyCellProtocol?
  • в обработчике didTapXXX или didSelectRowAtIndexPath вашей ячейки вызовите self.cellDelegate?.didTapCell(), передав ожидаемые параметры
  • в вашем контроллере представления, реализовать MyCellProtocol
  • в cellForRowAtIndexPath вашего контроллера представления, при создании/снятии очереди с ячейки установите cellDelegate свойства cellDelegate значение self

В этот момент, когда в вашей ячейке выполняется didTapCell, didTapCell метод didTapCell контроллера представления, и оттуда вы можете делать все, что вам нужно для достижения.

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

Ответ 2

extension UIView {
    var parentViewController: UIViewController? {
        var parentResponder: UIResponder? = self
        while parentResponder != nil {
            parentResponder = parentResponder!.next
            if let viewController = parentResponder as? UIViewController {
                return viewController
            }
        }
        return nil
    }
}

Внутри твоей клетки

if let myViewController = parentViewController as? MyViewController {
    print(myViewController.title)
}

Ответ 3

Я не думаю, что вы должны это сделать, и, вероятно, вы делаете что-то неправильно, но если вам действительно нужно это, то просто получите свойство в своем классе CustomCell.

var viewController : UIViewController

то при создании ячейки в cellForRowAtIndexPath установите свойство

cell.viewController = self

после этого вы можете легко получить доступ к контроллеру представления из кода ячейки:

self.viewController.doSomething()

Но опять же, на мой взгляд, вы должны перепроектировать свой код. Ячейка не должна заботиться о контроллере. Он должен заботиться только о том, чтобы показывать себя и ничего больше

Ответ 4

Лучший способ - реализовать делегирование. Ваш делегат сообщит контроллеру просмотра о нажатии кнопки. И, в свою очередь, ваш контроллер просмотра (который соответствует протоколу для вышеуказанного делегата) будет обрабатывать задачу, которую вы хотите выполнить при событии клика. (Учебники по шаблонам делегаций доступны в Интернете, вы можете пройти через них, если хотите знать, как делать делегирование).

Ответ 5

добавить расширение

 extension UITableViewCell {

        var viewControllerForTableView : UIViewController?{
            return ((self.superview as? UITableView)?.delegate as? UIViewController)
        }

    }

теперь downCast как ниже

   if let viewController = self.viewControllerForTableView as? AnyController{

       print(viewController.variable)

   } 

,

Ответ 6

Прочитайте другие комментарии о том, что вы действительно хотите использовать альтернативный подход, прежде чем пытаться это сделать, но с помощью этого расширения вы сможете перейти к dataSource и delegate, оба из которых должны быть UITableViewController

extension UITableViewCell {
    var tableView:UITableView? {
        get {
            for var view = self.superview ; view != nil ; view = view!.superview {
                if view! is UITableView {
                    return (view! as UITableView)
                }
            }
            return nil
        }
    }

    var tableViewDataSource:UITableViewDataSource? {
        get {
            return self.tableView?.dataSource
        }
    }

    var tableViewDelegate:UITableViewDelegate? {
        get {
            return self.tableView?.delegate
        }
    }
}