Recently I was asked to implement CollectionView with sections on Xamarin.iOS. In that project, we were using MVVMCross. I knew there is an option to do it on iOS native, so I thought of a solution on how to do it in Xamarin. Unfortunately, I didn’t find a sample code so I had to figure it out on my own 😢
In this article, I will show you how to implement Sectioned UICollectionView on Xamarin. Although, in the sample code, I am using MVVMCross to handle my bindings etc. this doesn’t mean that it works only for this framework. It’s cross framework one 😉
For the purpose of this tutorial, I am going to create a list of books. There will be several categories and each category can contain a different amount of books. Let’s go!
If you came only for the code, at the end of this article you can find a link to sample repository on Github.
Disclaimer
One more thing before we start: I don’t think this solution is the perfect one. It was constructed based on SWIFT code, StackOverflow answers and other small hints. I’ve just put it all together and made a sample.
To make my UI nicer I added FFImageLoading library, so I can show books thumbnails.
Step by step solution
Having an introduction let’s proceed with some coding. Firstly, create your UICollectionView and add it to your View/page. Basically, this step truly does not matter — you simply need to have UICollectionView added.
In the next step (secondly) I’d suggest you should create your ItemCells & HeaderCell. In order to create your ItemCells, you need to create a class that derives from MvxCollectionViewCell . You can do it by either creating a XIB file or .cs file. Populate the view, create the bindings and your are done. Mine cell looks like this
As you can see I am doing everything in code. Three of my elements are bindable and that’s all. Not that complex. Let’s proceed to the HeaderView. Similar to the ItemCell you need to create a class that inherits from UICollectionReusableView. Again, either create a XIB or .cs file. I will proceed with .cs file. Here is what I have:
This one is even simpler than the cell itself. The header only contains text. Pff. Easy. By now, we have created UICollectionView, ItemCells & HeaderView. In order to combine everything, we need to implement CollectionViewSource. Let’s talk about it in the next paragraph.
CollectionViewSource with header
Normally if we want to populate the TableView of CollectionView with a simple list we need to bind to ItemsSource. This time it is different. We can’t simply use ItemsSource as we need to combine the Items with the headers. In order to it I’ve created a class SectionItem — it has two properties: Header object (in my case HeaderText) and collection.
In my ViewModel I have ObservableCollection<SectionItem> SectionedList {get;set;}
which contains Sections with Items.
The most interesting part it the logic behind CollectionViewSource. Let me explain it by example.
Although I hope this code is pretty obvious, I’d like to put a stress on the following methods: NumberOfSections, GetItemsCount, GetItemAt, GetViewForSupplementaryElement, GetOrCreateCellFor.
I won’t get into many details as this is well documented on Apple’s pages but those are the methods that are responsible for making our SectionedCollectionView work.
A! I’ve almost forgotten: don’t forget to register your header by callingRegisterClassForSupplementaryView
on your Collection!
Conclusion
CollectionViews combined with FlowLayout are powerful controls on iOS. Adding headers and footers gives them extra powers. I always like to see them when using an iPad or bigger iPhone screens. They look nicer then TableViews, they perform good and they are really user-friendly.
I really hope that someone will find this post helpful. As I have stated in the introduction, I didn’t find a similar article on the web so I decided to write one on my own.
If you found any mistakes or something is unclear, please don’t hesitate to ask me by writing a comment. If you found this article useful, please show me some love and click the clap button below. It keeps me motivated!
Sample repository available on Github.
Article also available on Medium
Great Article!
I have a small suggestion. MvvmCross has https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/Platforms/Ios/Binding/Views/MvxCollectionReusableView.cs
which is a UICollectionReusableView that supports binding. Using this as the base class for BookHeader, it would be easier to wire up binding to corresponding property in VM.