毒蛇句柄table 单元动作
Viper handle table cell action
在 Viper 架构中处理单元操作的最佳方式是什么?这是我的基本 VC:
class StoriesViewController: BaseViewController {
var presenter: StoriesPresenterInput?
private var stories: [Story] = [] {
didSet {
guard let contentView = self.contentView as? StoriesView else { return }
contentView.refresherControl.endRefreshing()
contentView.activityView.stopAnimating()
if stories.count == 0 {
contentView.collectionView.setNoDataPlaceholder()
} else {
contentView.collectionView.removeNoDataPlaceholder()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.presenter?.viewDidLoad()
}
}
extension StoriesViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.stories.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "storiesCell", for: indexPath) as! StoriesCollectionViewCell
cell.story = stories[indexPath.item]
return cell
}
}
在经典 MVC 中,我会在我的单元格中创建用于点击和委托的协议:
protocol StoryCellProtocol: class {
func didTapUser(user: User)
}
class StoryCell: UICollectionViewCell {
weak var delegate: StoryCellProtocol?
}
我的 VC 在 cellForRow:
中的设置委托
cell.delegate = self
如何在 VIPER 中做同样的事情?
恕我直言,最好的方法是直接将协议一致性添加到您的 Presenter。
class StoriesPresenterInput: ..., StoryCellProtocol
并在 cellForItem
中分配委托:
cell.delegate = presenter
由于演示者中的任何用户交互都应该 parsed/processed,因此您还可以有效地删除视图和演示者之间的(主观上)冗余重定向。
有很多好的方法,假设您的输入演示者是一个协议,一个好的方法:设置单元格中动作的协议,例如,设置动作单元格的协议:
protocol CellAction {
didAction()
}
并使用单元格 class 中的方法配置单元格,例如:
func config(action: CellAction, story: Story) {
//todo
}
这是棘手的部分,使用您的输入来设置演示者的协议,请记住,假设您的输入是一个协议,在 cellForRow 中使用如下:
let cellAction = presenter as! CellAction
cell.config(action: cellAction, story: story)
您需要为演示者设置一个扩展来设置协议
extension YourPresenter: CellAction {
func didAction() {
//todo
}
}
在 Viper 架构中处理单元操作的最佳方式是什么?这是我的基本 VC:
class StoriesViewController: BaseViewController {
var presenter: StoriesPresenterInput?
private var stories: [Story] = [] {
didSet {
guard let contentView = self.contentView as? StoriesView else { return }
contentView.refresherControl.endRefreshing()
contentView.activityView.stopAnimating()
if stories.count == 0 {
contentView.collectionView.setNoDataPlaceholder()
} else {
contentView.collectionView.removeNoDataPlaceholder()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.presenter?.viewDidLoad()
}
}
extension StoriesViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.stories.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "storiesCell", for: indexPath) as! StoriesCollectionViewCell
cell.story = stories[indexPath.item]
return cell
}
}
在经典 MVC 中,我会在我的单元格中创建用于点击和委托的协议:
protocol StoryCellProtocol: class {
func didTapUser(user: User)
}
class StoryCell: UICollectionViewCell {
weak var delegate: StoryCellProtocol?
}
我的 VC 在 cellForRow:
中的设置委托cell.delegate = self
如何在 VIPER 中做同样的事情?
恕我直言,最好的方法是直接将协议一致性添加到您的 Presenter。
class StoriesPresenterInput: ..., StoryCellProtocol
并在 cellForItem
中分配委托:
cell.delegate = presenter
由于演示者中的任何用户交互都应该 parsed/processed,因此您还可以有效地删除视图和演示者之间的(主观上)冗余重定向。
有很多好的方法,假设您的输入演示者是一个协议,一个好的方法:设置单元格中动作的协议,例如,设置动作单元格的协议:
protocol CellAction {
didAction()
}
并使用单元格 class 中的方法配置单元格,例如:
func config(action: CellAction, story: Story) {
//todo
}
这是棘手的部分,使用您的输入来设置演示者的协议,请记住,假设您的输入是一个协议,在 cellForRow 中使用如下:
let cellAction = presenter as! CellAction
cell.config(action: cellAction, story: story)
您需要为演示者设置一个扩展来设置协议
extension YourPresenter: CellAction {
func didAction() {
//todo
}
}