当我在屏幕上显示最后一个单元格时,我的许多tableView都需要一个加载更多数据的方法。为了避免多次实现相同的方法,我决定创建自己的UITableView基础子类,在显示最后一个单元格时,为方法调用tableView委托(视图控制器),要求它加载更多数据,如果数据加载成功,将重新加载表视图。我虽然这是非常合理的,特别是当我的应用程序中几乎每个表视图都需要此功能时。
不幸的是,tableView:willDisplayCell:forRowAtIndexPath:
是一个UITableViewDelegate方法。而且我很确定,将UITableView子类设为UITableViewDelegate是错误的。所以,那就是我需要创建一个基础UITableViewController类。但是如果实现了一个基础UITableViewController,我可能想要覆盖子类中的tableView:willDisplayCell:forRowAtIndexPath:
。
另外,我的一些tableView嵌入在ViewController中,而不是TableViewController(因为除了表View之外还有其他东西),所以这意味着我需要一个单独的UITableViewController和UIViewController子类。所以这只是让事情变得更复杂。
那么如何使这个“在显示最后一个单元格时加载更多数据”功能可重用(遵循MVC指南)?
编辑:所以我想我已经想出了如何开始。我想要一个基础TableViewDelegateClass,例如BaseTableViewDelegate。然后,我想将其子类化,覆盖tableView:willDisplayCell:forRowAtIndexPath:
,但调用super.tableView:willDisplayCell:forRowAtIndexPath
。现在,我还有一个问题。我想让它重新加载数据。但我觉得在tableView委托中引用tableView是一个坏主意(可能是一个引用循环)。协议有一个很好的解决方案吗?
EDIT3:我也在考虑另一种方法:
protocol MyTableViewDelegate: UITableViewDelegate {
func default_tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
func loadMoreData()
}
extension MyTableViewDelegate {
func default_tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
if(indexPath.section == tableView.numberOfSections - 1 && indexPath.row == tableView.numberOfRows(inSection: indexPath.section) - 1 )
{
self.loadMoreData()
}
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
self.default_tableView(tableView, willDisplay: cell, forRowAt: indexPath)
//do something else here that is not done in default_tableView
}
}
class MyView: UIView, MyTableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
self.default_tableView(tableView, willDisplay: cell, forRowAt: indexPath)
}
func loadMoreData()
{
loadMoreDataFromServer(){
tableView.reloadData()
}
}
}
但这看起来有点难看。
答案 0 :(得分:0)
您可以为UITableViewDelegate
创建扩展程序,并为其中的tableView:willDisplayCell:forRowAtIndexPath:
编写默认实现。然后,子类的每个实例都将调用此实现。
extension UITableViewDelegate {
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// do what you need here, each ViewController that conforms to UITableViewDelegate will execute this implementation unless told otherwise
}
}
修改强>
另一种选择是为需要该行为的所有ViewController
创建基础ViewControllers
。在这种情况下,您不需要继承UITableView
。
你创建一个这样的类:
class BaseViewControllerForReloadingTables: UIViewController, UITableViewDelegate {
private var needToLoadMoreData: Bool = false
@IBOutlet var reloadingTableView: UITableView!
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if needToLoadMoreData {
loadMoreData()
}
}
private func loadMoreData() {
//load data
//if loading was successful
if reloadingTableView != nil {
reloadingTableView.reloadData()
}
}
}
然后,需要向表中加载更多数据的每个ViewController
都继承自此类。例如:
class ReloadingTableViewController1: BaseViewControllerForReloadingTables {
}
和
class ReloadingTableViewController2: BaseViewControllerForReloadingTables {
}
在这些子类中,UITableView
为reloadingTableView
。调用其委托函数时,将执行超类中的实现。这样,数据加载和表格重新加载在一个地方处理,但以适当的方式处理每个ViewControllers
。
当然,您可以为BaseViewControllerForReloadingTables
课程添加更多常用功能 - 取决于您的屏幕有多少相似的行为。
希望它有所帮助。