如何从Swift中的uitableviewcell类引用控制器

问题描述 投票:32回答:6

我有以下内容

  1. 视图控制器
  2. 的tableView
  3. 定制单元格

我使用NIB(.xib文件)作为单元格,它使用CustomCell类。此自定义单元格类处理IBAction以触摸单元格的按钮。我想引用ViewController及其中的一些变量。我该怎么做(访问ViewController)?

谢谢!

ios cocoa-touch uitableview swift uikit
6个回答
47
投票

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

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

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

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

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


19
投票
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)
}

12
投票

我不认为你应该这样做,可能你做错了但是如果你真的非常需要它,那么你的CustomCell课程中就有了一个属性。

var viewController : UIViewController

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

cell.viewController = self

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

self.viewController.doSomething()

但是,在我看来,你应该重新设计你的代码。单元格不应该关心控制器。它应该只关心显示自己而不是其他任何东西


3
投票

添加扩展名

 extension UITableViewCell {

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

    }

现在downCast如下

   if let viewController = self.viewControllerForTableView as? AnyController{

       print(viewController.variable)

   } 

.


2
投票

最好的方法是实现委托。您的代表将通知视图控制器有关按钮单击的信息。而且,您的视图控制器(符合上述委托的协议)将处理您要对点击事件执行的任务。 (授权模式教程可在线获取。如果您想知道如何进行授权,可以查看它们)。


0
投票

在尝试之前阅读其他关于真正想要使用替代方法的评论,但使用此扩展将允许您到达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
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.