使用共享数据源的多个表视图,但行数不同



我有几个表视图在我的应用程序中使用一个名为TaskListDataSource类的数据源实例,符合UITableViewDataSource

class TaskListDataSource: NSObject {
typealias TaskCompletedAction = () -> Void

private var tasks: [Task] = SampleData.tasks
private var taskCompletedAction: TaskCompletedAction?

init(taskCompletedAction: @escaping TaskCompletedAction) {
self.taskCompletedAction = taskCompletedAction
super.init()
}
}
extension TaskListDataSource: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tasks.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell", for: indexPath) as? TaskCell else {
fatalError("Unable to dequeue TaskCell")
}
cell.configure(task: tasks[indexPath.row]) {
self.tasks[indexPath.row].completed.toggle()
self.taskCompletedAction?()
}
return cell
}
}

我通过依赖注入传入实例,并像这样设置tableview数据源。我对所有使用这个数据源对象的视图控制器都这样做。

var taskListDataSource: TaskListDataSource

init?(coder: NSCoder, taskListDataSource: TaskListDataSource) {
self.taskListDataSource = taskListDataSource
super.init(coder: coder)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "TaskCell", bundle: nil), forCellReuseIdentifier: "taskCell")
tableView.dataSource = taskListDataSource
}

然而,我想实现一种方式,使在一个UITableViewControllers的行数被限制为3行。目前,由于下面的代码片段,它将始终只显示任务数组中的任务总数。

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

在每个表视图上,它显示了任务的总量,但我想要一种方式,我可以以某种方式保持cellForRowAt函数的可重用性,但使numberOfRows函数动态

你可以添加一个字典来保存每个tableview的限制

...
private maxRows: [String: Int?] = [:]
...

添加一个函数来处理绑定数据源

...
func add(_ tableView: UITableView, maxRows: Int? = nil) {
if let id = tableView.id {
self.maxRows[id] = maxRows
}
tableView.datasource = self
}
...

则数据源函数numberOfRowsInSection变为

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let id = tableView.id {
return maxRows[id] ?? tasks.count
}
return tasks.count
}

并将tableview数据源设置为

override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "TaskCell", bundle: nil), forCellReuseIdentifier: "taskCell")
taskListDataSource.add(tableView, maxRow: 3) 
}

tableView.id可以是任何你想要的。例如:你子类化UITableView并添加一个属性

class UITableViewWithID: UITableView {
var id: String?
}

最新更新