我认为我完全理解授权的概念,我的问题是当我们这样做时:
class someViewController : UIViewController, UITableViewDelegate{
}
是否永远可能我们不希望将tableView.delegate
设置为self
?
如果没有任何机会,为什么Xcode迫使我们在这里做一些额外的工作?
如果tableView.delegate
有可能设置为self
以外的其他内容......那么这是什么?你能举一些例子吗?
答案 0 :(得分:4)
在所需的ViewController中提到tableView.delegate = self
或tableView.dataSource = self
时,这意味着ViewController会说"我负责实现这些委托/数据源方法",意味着这个ViewController(self
)正在处理提供所需的方法,让tableView知道它应该是什么样子/行为。
参考您的问题:
我们是否有可能不想设置 tableView.delegate to self?
实际上它是可能的,但这导致让tableView显示为一个空的tableView(其中没有行),因为没有人告诉它应该如何看起来/表现。
如果tableView.delegate有可能被设置为其他东西 比自己......那是什么?你能举一些例子吗?
是的,你可以,tableView.dataSource / delegate不必分配给包含这个tableView的同一个Viewcontroller(但我发现它更具可读性和可理解性)。
例如:
在下面的代码片段中,我将tableView的dataSource分配给另一个 .swift 文件上的另一个独立的类(甚至不是UIViewController),它完全正常工作:
import UIKit
// ViewController File
class ViewController: UIViewController {
var handler: Handler!
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
handler = Handler()
tableView.dataSource = handler
}
}
处理程序类:
import UIKit
class Handler:NSObject, UITableViewDataSource {
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell")
cell?.textLabel?.text = "row #\(indexPath.row + 1)"
return cell!
}
}
输出正常工作。
答案 1 :(得分:2)
我们是否有可能不想设置 tableView.delegate to self
是的,如果你要在它自己的类中实现数据源和委托。
为什么Xcode迫使我们在这里做一些额外的工作?
尽可能让我们的架构自由。
使用单独的数据源和委托类的示例。
override func loadView() {
// this will create default blank view and set it to the 'view' property
super.loadView()
let userProfileView = UserProfileView()
view.addSubview(userProfileView)
// pin userProfileView left and right edge to superview's left and right edges
// its top to view controller's topLayoutGuide
// and its bottom to view controller's bottomLayoutGuide
}
如果您允许视图控制器保存委托和数据源的不同实现,那么这允许更高的可重用性并且有利于组合而不是继承。
您处理较小的类,并且更容易测试和维护。
甚至可以设计完整的应用程序,不需要任何视图控制器子类。
数据源/委托设计可以随心所欲。
作为一个例子,我想向您展示我的一个新项目:TaCoPopulator。它是一个框架,通过将其拆分为不同的任务来透明地填充表视图和集合视图,以遵循SOLID原则:
class TableViewDatasource: NSObject, UITableViewDataSource {
// implement datasource
}
class TableViewDelegate : NSObject, UITableViewDelegate {
// implement delegate
}
class ViewController: UIViewController {
IBOutlet weak var tableView: UITableView! {
didSet {
tableView.dataSource = tableViewDatasource
tableView.delegate = tableViewDelegate
}
}
let tableViewDatasource = TableViewDatasource()
let tableViewDelegate = TableViewDelegate()
}
import UIKit
class CollectionViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
private var datasource: ViewControllerDataSource<UICollectionView>?
override func viewDidLoad() {
super.viewDidLoad()
self.datasource = ViewControllerDataSource(with: collectionView)
}
}
import UIKit
class TableViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
private var datasource: ViewControllerDataSource<UITableView>?
override func viewDidLoad() {
super.viewDidLoad()
self.datasource = ViewControllerDataSource(with: tableView)
}
}
import TaCoPopulator
class IntDataProvider: SectionDataProvider<Int> {
override init(reuseIdentifer: @escaping (Int, IndexPath) -> String) {
super.init(reuseIdentifer: reuseIdentifer)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
self.provideElements([1,2,3,4,5,6,7,8,9])
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
self.provideElements(self.elements() + [10, 11, 12, 13, 14, 15])
}
}
}
}
答案 2 :(得分:1)
我们是否有可能不想将tableView.delegate设置为self?
什么是tableView.delegate
?您的班级someViewController
不是UITableViewController
的子类(并且没有tableView
属性)。它甚至不知道你处理表视图。
您的类型声明符合UITableViewDelegate
的事实并没有明确说明它应该设置在哪个实际的表视图实例上。
如果tableView.delegate有可能被设置为self以外的东西......那么这是什么?
通常,将功能分成多种类型以降低视图控制器的复杂性是明智的。您的someViewController
可能具有viewModel
属性,可处理有关表格视图的所有内容。