Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UICollectionView and MVVM

I'm trying to understand how I can use MVVM to develop a reusable UICollectionViewController.

Suppose you create a view model for each type of UICollectionViewCell

struct CollectionTestCellViewModel {
    let name: String
    let surname: String

    var identifier: String {
        return CollectionTestCell.identifier
    }

    var size: CGSize?
}

And the cell:

class CollectionTestCell: UICollectionViewCell {
    @IBOutlet weak var surnameLabel: UILabel!
    @IBOutlet weak var nameLabel: UILabel!

    func configure(with viewModel: CollectionTestCellViewModel) {
        surnameLabel.text = viewModel.surname
        nameLabel.text = viewModel.name
    }
}

In the view controller I have something like that:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let viewModel = sections[indexPath.section][indexPath.row]
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: viewModel.identifier, for: indexPath)
    configure(view: cell, with: viewModel)
    return cell
}

So far no problem. But consider now this method of UICollectionViewDelegateFlowLayout:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let viewModel = sections[indexPath.section][indexPath.row]
    return viewModel.size ?? UICollectionViewFlowLayoutAutomaticSize
}

The point is I have layout information (the size of the cell) in the view model. This allows me to put in my view controller the layout delegate methods, but I don't know if this violate the MVVM pattern.

The final question is: what should I put inside the view model (of a cell for example)? It is "allowed" to put layout data inside the view model?

Thanks

like image 943
alfogrillo Avatar asked Feb 28 '18 19:02

alfogrillo


1 Answers

In MVVM the View consists of only visual elements. We only do things like layout, animation, initializing UI components, etc. There’s a special layer between the View and the Model called the ViewModel.

The ViewModel provides a set of interfaces, each of which represents a UI component in the View. We use a technique called “binding” to connection UI components to ViewModel interfaces. So, in MVVM, we don’t touch the View directly, we deal with business logic in the ViewModel and thus the View changes itself accordingly.

We write presentational things such as converting Date to String in the ViewModel instead of the View.

Therefore, it becomes possible to write a simpler test for the presentational logic without knowing the implementation of the View.

To learn more about MVVM in iOS read this article.

like image 59
Eugene Karambirov Avatar answered Nov 19 '22 06:11

Eugene Karambirov