繁体   English   中英

如何从 UITableViewCell 类引用 UITableViewController?

[英]How to reference UITableViewController from a UITableViewCell class?

我有以下几点:

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

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

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

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

我不会在单元格和视图控制器之间创建这种依赖关系 - 这会使架构更加复杂并且单元格不可重用。

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

  • 使用一个方法didTapCell创建一个协议MyCellProtocol ,接受一个UITableViewCell和/或一些你想传递给视图控制器的自定义数据
  • 在您的自定义单元格中创建一个公共委托属性: weak var cellDelegate: MyCellProtocol?
  • 在您的单元格的didTapXXX处理程序或didSelectRowAtIndexPath中,调用self.cellDelegate?.didTapCell() ,传递预期的参数
  • 在您的视图控制器中,实现MyCellProtocol
  • 在视图控制器的cellForRowAtIndexPath中,在创建/出列单元格时,将其cellDelegate属性设置为self

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

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

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

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

weak var viewController : UIViewController

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

cell.viewController = self

之后,您可以轻松地从单元代码中访问视图控制器:

self.viewController.doSomething()

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

添加扩展

 extension UITableViewCell {

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

    }

现在 downCast 如下

   if let viewController = self.viewControllerForTableView as? AnyController{

       print(viewController.variable)

   } 

.

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

在尝试之前阅读有关真正想要使用替代方法的其他评论,但使用此扩展将允许您访问dataSourcedelegate这两者都应该是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
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM