How to reference controller from a uitableviewcell class in Swift

醉酒当歌 提交于 2019-12-17 17:48:09

问题


I have the following

  1. ViewController
  2. tableView
  3. CustomCell

I used a NIB(an .xib file) for the cell, which uses a CustomCell class. This custom cell class handles IBAction for some touch on the cell's button. I'd like to reference the ViewController and some of its variables within it. How am I supposed to do it(accessing ViewController)?

Thanks!


回答1:


I wouldn't create this kind of dependency between the cell and the view controller - that makes the architecture more intricate and the cell not reusable.

I suggest you to use the delegation pattern, which may sound a little complicated - although you're already using (UITableViewDelegate is a typical example):

  • create a protocol MyCellProtocol with one method didTapCell, accepting a UITableViewCell and/or some custom data you want to pass to the view controller
  • create a public delegate property in your custom cell: weak var cellDelegate: MyCellProtocol?
  • in the didTapXXX handler or didSelectRowAtIndexPath of your cell, call self.cellDelegate?.didTapCell(), passing the expected parameters
  • in your view controller, implement the MyCellProtocol
  • in cellForRowAtIndexPath of your view controller, when creating/dequeuing the cell, set its cellDelegate property to self

At this point, when a tap is done in your cell, the didTapCell method of the view controller is called, and from there you can do whatever you need to achieve.

The key point is: rather than making the cell handle the cell tap/selection, notify the view controller and let it do the job.




回答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
    }
}

Inside your cell

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



回答3:


I don't think you should do that and probably you're doing something wrong but if you really-really need it then just have a property in your CustomCell class.

weak var viewController : UIViewController

then when you create the cell in cellForRowAtIndexPath set the property

cell.viewController = self

after that you can easily access the view controller from within the cell code:

self.viewController.doSomething()

But again, in my opinion, you should redesign your code. The cell should not care about the controller. It should care only about displaying itself and nothing else




回答4:


add Extension

 extension UITableViewCell {

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

    }

now downCast as below

   if let viewController = self.viewControllerForTableView as? AnyController{

       print(viewController.variable)

   } 

.




回答5:


Best way is to implement Delegation. Your delegate will inform the view controller about the button click. And, In turn your view controller (who is conforming the protocol for above delegate) will handle the task that you want to perform on click event. (Delegation pattern tutorials are available online. you can go through them if you want to know how to do delegation).




回答6:


Read the other comments about really wanting to use an alternate approach before trying this, but using this extension will allow you to get to the dataSource and delegate both of which should be the 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
        }
    }
}


来源:https://stackoverflow.com/questions/26467606/how-to-reference-controller-from-a-uitableviewcell-class-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!