ios 如何从 UITableViewCell 类引用 UITableViewController?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26467606/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 03:16:24  来源:igfitidea点击:

How to reference UITableViewController from a UITableViewCell class?

ioscocoa-touchuitableviewswiftuikit

提问by Norly Canarias

I have the following:

我有以下几点:

  1. UITableViewController
  2. UITableView
  3. Custom UITableViewCell subclass
  1. UITableViewController
  2. 用户界面
  3. 自定义 UITableViewCell 子类

I used a .xib file for the cell, which is a CustomCellsubclass. This custom cell handles IBActions for some touch events on the cell's buttons.

我为单元使用了一个 .xib 文件,它是一个CustomCell子类。此自定义单元格处理单元格按钮上某些触摸事件的 IBAction。

I'd like to reference the ViewController and some of its variables from the cell.

我想从单元格中引用 ViewController 及其一些变量。

How am I supposed to access the UITableViewController from the UITableViewCell class?

我应该如何从 UITableViewCell 类访问 UITableViewController?

回答by Antonio

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 (UITableViewDelegateis a typical example):

我建议你使用委托模式,这听起来可能有点复杂——尽管你已经在使用(UITableViewDelegate是一个典型的例子):

  • create a protocol MyCellProtocolwith one method didTapCell, accepting a UITableViewCelland/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 didTapXXXhandler or didSelectRowAtIndexPathof your cell, call self.cellDelegate?.didTapCell(), passing the expected parameters
  • in your view controller, implement the MyCellProtocol
  • in cellForRowAtIndexPathof your view controller, when creating/dequeuing the cell, set its cellDelegateproperty to self
  • MyCellProtocol用一种方法创建一个协议didTapCell,接受一个UITableViewCell和/或一些你想传递给视图控制器的自定义数据
  • 在您的自定义单元格中创建一个公共委托属性: weak var cellDelegate: MyCellProtocol?
  • didTapXXX处理程序或didSelectRowAtIndexPath您的单元格中,调用self.cellDelegate?.didTapCell(),传递预期参数
  • 在您的视图控制器中,实现 MyCellProtocol
  • cellForRowAtIndexPath您的视图控制器中,在创建/出列单元格时,将其cellDelegate属性设置为self

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

此时,当在您的单元格中完成点击时,将didTapCell调用视图控制器的方法,然后您可以执行任何您需要实现的操作。

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

关键是:不是让单元格处理单元格点击/选择,而是通知视图控制器并让它完成工作。

回答by Blank

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)
}

回答by Andrey Chernukha

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 CustomCellclass.

我认为您不应该这样做,而且您可能做错了什么,但是如果您真的需要它,那么只需在您的CustomCell班级中拥有一个属性即可。

weak var viewController : UIViewController

then when you create the cell in cellForRowAtIndexPathset the property

然后当您在cellForRowAtIndexPath设置属性中创建单元格时

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

但同样,在我看来,你应该重新设计你的代码。单元不应该关心控制器。它应该只关心展示自己而不关心其他

回答by Gopal krishan

add Extension

添加扩展

 extension UITableViewCell {

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

    }

now downCast as below

现在 downCast 如下

   if let viewController = self.viewControllerForTableView as? AnyController{

       print(viewController.variable)

   } 

.

.

回答by Tejas

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).

最好的方法是实现委托。您的委托将通知视图控制器有关按钮单击的信息。并且,反过来,您的视图控制器(符合上述委托的协议)将处理您要在单击事件上执行的任务。(委托模式教程可以在网上找到。如果你想知道如何进行委托,你可以通过它们)。

回答by David Berry

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 dataSourceand delegateboth of which should be the UITableViewController

在尝试之前阅读有关真正想要使用替代方法的其他评论,但使用此扩展程序将允许您到达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
        }
    }
}