【发布时间】:2021-10-29 01:04:26
【问题描述】:
我的应用中有几个表视图,它们使用一个名为 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
}
但是我想实现一种方法,以便在其中一个 UITableViewController 上将行数限制为 3 行。目前因为下面的代码 sn-p 它总是只显示任务数组中的任务总数。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tasks.count
}
在每个 tableview 上,它显示了任务的总数,但我想要一种方法,我可以以某种方式保持 cellForRowAt 函数的可重用性,同时使 numberOfRows 函数动态化。
【问题讨论】:
-
将属性添加到
TaskListDataSource,以了解您是否应该“应限制为 3”(如果任务较少,则应限制为更少)并检查numberOfRowsInSection中的值? -
@Larme 因为我只有这个TaskListDataSource 的一个实例,所以每次用户查看一个新的tableview 时都需要更新这个属性。所以我必须不断地设置属性并重新加载viewDidAppear中的tableview。还有比这更清洁的方法吗?
-
最好的办法可能是分开你的班级。一部分负责保存数据(例如 TaskListDataStore)并且是单个实例,另一部分负责显示数据(TaskListDataSource)。然后,您可以从
TaskListDataSource为每个控制器创建一个实例。 -
@Johannes Starke 我非常喜欢这个。它适用于我创建的通用模型存储类。所以我会将该存储注入到每个控制器中,并通过 TaskListDataSource 对象的每个初始化程序将其提供给它。但是,当进行更改时,我将如何使所有 tableview UI 保持同步? (例如,指示是否完成的任务复选框)
-
在大多数情况下,如果您在 viewWillAppear 中重新加载数据就足够了,对吧?否则,您还可以将经典委托(或回调)添加到您的商店,以便 ViewController 可以注册更改。
标签: ios swift uitableview