Unifying Table and Collection Views Presentation Logic Within MVVM. Part 3

Isa Aliev
3 min readApr 2, 2022

In the previous parts I mostly described the view and viewModels’ list binding technic that allows you to build your lists in declarative way. In this part I am going to show how you can completely erase the difference between building TableView and CollectionView.

There is a problem behind any solution, so the problem for me and my team was the following:

Someone (A person) prefers building UI using UITableView, someone — UICollectionView (B person). This means that one will create UITableViewCell subclasses and other — UICollectionViewCell subclasses. At some point A is building a view that contains completely the same cell as B person has built, but the problem is that B subclassed UICollectionViewCell, but A needs UITableViewCell subclass, so B will most likely create exactly the same cell which only differs in its parent class. It hits overall reusability and leads to multiple sources that must be modified together every time a change is needed.

The solution is pretty simple: containerization.

Instead of creating UITableViewCell/UICollectionViewCell subclasses, we create UIView subclasses. We subclass UITableViewCell/UICollectionViewCell only to create a few containers, that are able to embed any view inside them.

The picture below will give you better understanding.

The container classes are generic classes, so we can put anything inside them. Here is a shortened implementation of ContainerCell:

Do not forget that all of this is described in the context of two previous parts.

Other containers has similar implementations. You can create your own containers with an insets you need for the content. For example, we also have ContainerCell16<T> container that insets the content horizontally by 16 points.

Remember CollectionItemsViewModelDependencyManager from previous parts? Let’s see how dependencies will be described when we move to the approach described.

For example, this:

Will now look like this:

The power of this approach is also revealed when in some point in time you decide to move from collection view to table view. All you have to do is to change your collection view to table view and alter manager dependencies to use table view cell container:

There is no header here because UITableView uses its delegate for headers, not dataSource, so this part is to be implemented separately.

It usually takes me under 1 minute to switch between collection view and table view. If you do not remember, all we do in our screen’s view to setup list’s dataSource is:

So you just switch to table view and you are all good.

For details you can check my framework sources:

Excuse me for not having documentation, the framework has no popularity, so I’m not so motivated to make it clear and beautiful. I will be happy for any suggestions and contributions as well as constructive criticism.

P.S.: In previous parts I described the approach using RxDataSources framework because of higher popularity, but I personally prefer Bond because I have control over Mutable(!)Observable(!)Array structure not just pushing new data in an observable variable and hoping everything will go well.

Thank you for reading!

--

--