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
How to reference UITableViewController from a UITableViewCell class?
提问by Norly Canarias
I have the following:
我有以下几点:
- UITableViewController
- UITableView
- Custom UITableViewCell subclass
- UITableViewController
- 用户界面
- 自定义 UITableViewCell 子类
I used a .xib file for the cell, which is a CustomCell
subclass. 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 (UITableViewDelegate
is a typical example):
我建议你使用委托模式,这听起来可能有点复杂——尽管你已经在使用(UITableViewDelegate
是一个典型的例子):
- create a protocol
MyCellProtocol
with one methoddidTapCell
, accepting aUITableViewCell
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 ordidSelectRowAtIndexPath
of your cell, callself.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 itscellDelegate
property toself
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 didTapCell
method 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 CustomCell
class.
我认为您不应该这样做,而且您可能做错了什么,但是如果您真的需要它,那么只需在您的CustomCell
班级中拥有一个属性即可。
weak var viewController : UIViewController
then when you create the cell in cellForRowAtIndexPath
set 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 dataSource
and delegate
both 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
}
}
}