如何解决在 VIPER 中构建 UITableView
想象一下我有一个像这样的 viewForHeaderInSection
:
注意:目前是用 MVP 编写的,我正在尝试将其重构为 VIPER
func tableView(_ tableView: UITableView,viewForHeaderInSection section: Int) -> UIView? {
guard let header = tableView.dequeueReusableheaderfooterView(withIdentifier: DetailsSectionHeaderView.identifier) as? DetailsSectionHeaderView,let section = PresenterEnum.Sections(rawValue: section),section != .fourth,let presenter = presenter else {
return nil
}
switch section {
case .first:
header.configure(StringConstants.first.localized,showButton: false,isSelected: false)
case .second:
let secondarray = presenter.secondarrayCount
header.configure(StringConstants.second.localized,showButton: secondarray > 3,isSelected: presenter.isExpanded(section.rawValue))
header.showMoreAction = { [weak self] in
self?.handleMoreAction(tableView,in: section.rawValue)
}
case .third:
let thirdCount = presenter.thirdArrayCount
header.configure(StringConstants.third.localized,showButton: thirdArrayCount > 3,isSelected: presenter.isExpanded(section.third))
header.showMoreAction = { [weak self] in
self?.handleMoreAction(tableView,in: section.rawValue)
}
default:
return nil
}
return header
}
private func handleMoreAction(_ tableView : UITableView,in section : Int){
guard let presenter = presenter else {return}
tableView.beginUpdates()
let isExpanded = presenter.isExpanded(section)
var indexPaths = [IndexPath]()
for i in presenter.minimumRowCount..<presenter.totalRowCountForSection(section){
indexPaths.append([section,i])
}
if isExpanded{
tableView.deleteRows(at: indexPaths,with: .automatic)
}else{
tableView.insertRows(at: indexPaths,with: .automatic)
}
presenter.updateExpansion(section)
tableView.endUpdates()
}
UITableViewDelegate
和 UITableViewDataSource
是 View
的一部分。但它们是被动的,不应真正向 presenter
请求信息。但同时如何显示视图信息属于presenter
。
根据上面的定义,我无法弄清楚如何重构下面的代码。这似乎不正确,因为关于该部分应该显示什么的逻辑在视图中以及如何处理 showMoreAction
。
所以我的问题是: 构建上述两种方法以使其更符合 VIPER 标准的“正确”方法是什么?
解决方法
1 创建允许视图和演示者传递数据的协议, 示例:
protocol PresenterProtocol where Self: UIViewController{
var table: UITableView {get}
}
-
在Presenter中创建弱视图控制器引用,符合Presenter协议, 例子:
class Presenter: NSObject { weak var viewController: PresenterProtocol{ didSet{ connectVC() } } func connectVC(){ self.viewController.table.delegate = self self.viewController.table.dataSource = self } }
-
现在,当您将 tableview 委托和数据源分配给演示者时,您可以进行扩展,例如:
extension Presenter: UITableViewDataSource,... // cell for row methods ..
-
那么你应该改变你的视图(ViewController)
class ViewController: UIViewController{ @IBOutlet weak var tableView: UITableView? var presenter: Presenter? viewDidLoad(){ super.viewDidLoad() presenter = Presenter() presenter.viewController = self } }
所以你将你的 vc 分配给了演示者的 viewController 现在你需要的只是让你的 VC 符合 PresenterProtocol
extension ViewController: PresenterProtocol{
var table: UITableView {
return self.tableView
}
}
现在你的 VC 是干净的,所有的逻辑都包含在演示者中,当然可以更容易,但我只是展示了正确的方向
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。