为什么我必须设置dataSource并委托给self?

时间:2016-08-28 07:13:05

标签: ios swift uitableview

我正在快速学习,而我正在学习的课程教授tableViews。我必须设置TableViewController t包含UITableViewDataSourceUITableViewDelegate。然后,在viewDidLoad中,我必须设置

tableView.dataSource = self
tableView.delegate = self

为了使tableView出现并加载数据。

为什么我必须这样做?

6 个答案:

答案 0 :(得分:19)

既然你说过你正在学习斯威夫特只是想写一个赞美的答案。所有其他答案已经解释了为什么需要将委托设置为self或任何类的实例。但我仍然想到写这个答案只是为了提供更多的见解。

让我解释一下UITableViewDelegate& UITableViewDataSource是。 UITableViewDelegate& UITableViewDataSource是协议。什么是协议?您可以将协议视为一组操作。

例如 UITableViewDataSource 有一组动作/方法 tableView(:numberOfRowsInSection:) tableView( tableView:UITableView, cellForRowAtIndexPath indexPath:NSIndexPath)等等。

这个协议意味着如果你想将自定义数据提供给tableview,你需要遵守这个协议,即实现协议的非可选方法(你可以忽略可选方法)。

同样, UITableViewDelegate 有一组方法,例如 tableView(_ tableView:UITableView, heightForRowAtIndexPath indexPath:NSIndexPath) tableView(_ tableView:UITableView, didSelectRowAtIndexPath indexPath:NSIndexPath)等等。

UITableViewDelegate 协议意味着如果您希望在桌面视图中发生用户交互时收到通知,则需要符合协议,例如当用户点击tableview的单元格时。

现在,为什么要设置

tableView.dataSource = self
tableView.delegate = self

是因为您在ViewController,TableViewDatasource协议中实现协议(或符合协议)以向tableview提供您自己的数据,TableViewDelegate协议在用户与您的tableview交互时通知您的ViewController类。

实际上,您不会始终将协议一致性设置为 self ,您可以将其设置为实现协议的任何类的实例。

希望这有助于。

有关协议的更多参考,您可以查看:Swift 2 Tutorial Part 3: Tuples, Protocols, Delegates, and Table Views

答案 1 :(得分:7)

您必须设置数据源和视图委托才能使视图生效。那些不必是self(即控制器),它可以是一些其他对象(或两个其他对象,一个数据源和一个视图委托)。

您似乎已经在控制器中实现了两者的方法,因此它可以充当所有三个(控制器,数据源,视图委托)。但你还是要告诉它有关它的观点。

答案 2 :(得分:4)

我将为此提供详细说明。 在这里,UITableViewDataSource& UITableViewDelegate实际上是协议。不幸的是,UIKit Framework不是开源的。但我会向你保证,这是在引用很多文章后内部发生的事情。

协议就像篮球教练,有一些要求。他/她通过使用这些要求告诉玩家类,结构,枚举what to do?。但他/她doesn't knows how to do?由他们自己。因此,符合该协议的类或结构应该在实现扣篮时为这些要求提供实现。

protocol UITableViewDelegate {
 func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
}

协议被认为是DataSource协议,然后它总是包含所需的函数"返回类型"如下图所示。

protocol UITableViewDataSource {
 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
 func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
}

在自定义viewController中实现UITableView

class viewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    let tableView = UITableView()    

    override func viewDidLoad {
      tableView.delegate = self
      tableView.dataSource = self
    }

此处,tableView充当代理人(发件人)& viewController object i.e (self)作为代表(接收方)。

现在称为UITableView()

tableView对象具有UITableView()类&中类型的相应协议的两个可选存储属性。现在它被tableView称为

tableView.delegate: UITableViewDelegate?
tableView.dataSource: UITableViewDataSource?

要在UITableView中获取viewController。它应符合两个协议。 因此,viewController类对象已实现了这两种协议所需的所有功能。现在self可以用作UITableViewDelegate类型或UITableViewDataSource类型,因为协议可以用作符合它的类对象的类型。 现在,tableView的两个属性,即delegate& dataSource被分配给self,因为它具有相同的协议类型。

两个协议的非可选功能都在viewController类对象中实现,如下所示

协议UITableViewDelegate函数

func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
// Do further processes like pushing or poping another viewController
}

协议UITableViewDataSource函数

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 10
 }

func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    return UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
 }

1)当用户在某个部分中选择一行时,tableview(发件人)即UItableView()通过将数据传递到参数UITableViewDelegate和放大器来调用下面显示的tableView func ; indexPath viewController通过其delegate属性驻留在viewController对象(接收方)中。现在tableView.delegate?.tableView(UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 使用那些传递的数据来执行进一步的处理,例如推送或弹出到新的自定义viewController。

UITableViewDatasource

2)tableview协议内的函数向tableview(发件人)提供自定义数据。 viewController通过将数据传递给参数tableView&来调用数据源函数来询问indexPath对象。 viewController datasource通过其viewController属性驻留在tableview对象(接收方)中。现在tableview使用那些传递的数据&返回自定义数据tableView.dataSource?.tableView(UITableView, numberOfRowsInSection section: Int) -> returns "10" tableView.dataSource?.tableView(UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> returns "cell" 。现在tableView.delegate使用这些数据来创建" 10"一节中的细胞和那种"细胞"在indexpath

tableView.Datasource

因此我们分配self和& tableView.delegate tableView.Datasource self。它不符合议定书。但要初始化属性tableView& Delegate Datasource self。那么,self可以调用那些UIKit Framework& UIApplication通过它们驻留在UITableView的方法。

一个类被称为符合协议,只是实现其中的所有要求。这就是它,但不是通过将UICollectionView分配给其他人的属性。

最后,整个UITextField使用委托&所有类中的数据源设计模式,例如UIKit Framework,{{1}},{{1}},{{1}}&等等来传达数据。不幸的是,{{1}}不是开源的。

答案 3 :(得分:2)

设置tableView.datasource = self意味着调用此类将充当tableView的数据源提供程序,并实现了向tableView提供数据的函数填写tableView。

delegate也是如此。 delegate(self)类已经实现了在tableView上执行某些操作时将被调用的函数,就像在tableView的行中单击一样。

答案 4 :(得分:2)

设置委托会在委托对象和您的类之间创建连接。 Delegate对象处理表视图,并让您的类知道它何时完成。通过设置委托,您可以调整tableview的行为。

答案 5 :(得分:0)

加深对DataSource和Delegate的理解

Delegate 和 DataSource 都是一种称为 Delegation Pattern 的设计模式,该模式在 Apple FrameWork 尤其是 UIKit 中常用。

委托模式用于在两个对象之间进行通信,其中一个负责将任务委托给另一个对象。此模式分为三部分:

  1. 委托对象:保持对另一个对象的引用,并且 它包含允许您在需要时调用它的协议

  2. 委托协议:定义委托的方法名称。 (在创建委托之前,您必须了解协议,这将 在下一个参考文献中覆盖它。

  3. 委托:这是一个实现委托方法的对象。

当您创建一个委托对象时,它是 tableView。委托协议(UITableViewDelegate、UITableViewDataSource)实现到Delegate、ViewController。以 UITableViewDelegate 为例,委托对象检测到被选中的行,并使用实现的协议方法向委托发送消息,该方法允许委托通过改变其状态、外观等进行响应. 因此,委托的主要价值在于它允许您在一个中心对象中自定义 serval 对象的行为。

您可以转到 https://appdevelopments.co/reference/designpattern/delegation 以获得更好的理解。