Home > Software engineering >  Viper handle table cell action
Viper handle table cell action

Time:10-22

What is the best way to handle cell action in Viper architecture? Here is my basic 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
    }
}

In classic MVC, i would create a protocol for tap and delegate in my cell:

protocol StoryCellProtocol: class {
    func didTapUser(user: User)
}

class StoryCell: UICollectionViewCell {
weak var delegate: StoryCellProtocol?
}

The set delegate to my VC in cellForRow:

cell.delegate = self

How to do the same thing in VIPER?

CodePudding user response:

IMHO the best way would be to add the protocol conformance to your Presenter directly.

class StoriesPresenterInput: ..., StoryCellProtocol

and assign the delegate in cellForItem:

cell.delegate = presenter

Since any user interaction should be parsed/processed in the presenter, you would also be effectively removing the (subjectively) redundant redirection between view and presenter.

CodePudding user response:

there is many good ways for that, assuming your input presenter is a protocol, a good one: set to the protocol for the action in cell, for example, setup the protocol for the action cell:

    protocol CellAction {
          didAction()
    }

and configure your cell using a method in your cell class like:

   func config(action: CellAction, story: Story) {
         //todo
   }

here is the tricky part, using your input to setting up the protocol to presenter, REMEMBER, ASUMING YOUR INPUT IS A PROTOCOL, using in cellForRow like:

      let cellAction = presenter as! CellAction
      cell.config(action: cellAction, story: story)

you need setup an extension for your presenter to set the protocol

  extension YourPresenter: CellAction {
         func didAction() {
          //todo
         }
   }
  • Related