使用共享数据源但行数不同的多个表视图
Multiple tableviews using a shared datasource but varying number of rows
我的应用程序中有几个表格视图使用一个名为 TaskListDataSource class 的数据源实例,它符合 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
}
}
我通过依赖注入传入实例并像这样设置表视图数据源。我为所有使用此数据源对象的视图控制器执行此操作。
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
}
但是我想实现一种方法,以便在其中一个 UITableViewController 上将行数限制为 3 行。目前,由于以下代码片段,它将始终只显示任务数组中的任务总数。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tasks.count
}
在每个 tableview 上它显示了任务的总数,但我想要一种方法可以以某种方式保持 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
}
并将表视图数据源设置为
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?
}
我的应用程序中有几个表格视图使用一个名为 TaskListDataSource class 的数据源实例,它符合 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
}
}
我通过依赖注入传入实例并像这样设置表视图数据源。我为所有使用此数据源对象的视图控制器执行此操作。
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
}
但是我想实现一种方法,以便在其中一个 UITableViewController 上将行数限制为 3 行。目前,由于以下代码片段,它将始终只显示任务数组中的任务总数。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tasks.count
}
在每个 tableview 上它显示了任务的总数,但我想要一种方法可以以某种方式保持 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
}
并将表视图数据源设置为
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?
}