Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing UICollectionView layout depending on section

I am currently implementing a UICollectionView with several sections (let's say 4) like in the image below:

uicollectionview

From section 0 to section 2 it is just a UICollectionViewFlowLayout with different cell sizes for each section but for section 3, it is a custom layout (Waterfall layout).

I already have implemented the 2 different layouts and they work well in separate UICollectionView, but I have some trouble to switch between the 2 layouts in the same UICollectionView.

First of all is it possible to change the layout from a section to another and if it is by which way this can be accomplished.

like image 461
Florian Ldt Avatar asked Dec 04 '18 02:12

Florian Ldt


People also ask

How do you create a collection view with multiple sections?

You need to implement a custom UICollectionViewLayout. With a horizontal flow layout it's going to fill from top to bottom first, then move to the right. Since you have two rows, as specified in sizeForItemAt, section 0 will fill from top to bottom, then right to left, and so will section 1.

How do I set collection view layout?

To lay out UICollectionView cells in a simple grid, you can use UICollectionViewFlowLayout directly. For more flexibility, you can subclass UICollectionViewLayout to create advanced layouts.

How do I add a section title in UICollectionView?

There are no section headers in the UICollectionView. So for your first task, you'll add a new section header using the search text as the section title. To display this section header, you'll use UICollectionReusableView .


1 Answers

I think your question header is a bit misleading. You don't need to change the layout for each section. You need to show different layouts depending on section.

To achieve what you want you must subclass UICollectionViewLayout and then determine the layout depending on section. In your case I suggest you to subclass UICollectionViewFlowLayout as it takes a lot of heavy lifting.

Section 0 - Section 2 of your sample are easily achievable by using just UICollectionViewDelegateFlowLayout.

As you have "full width" cells there, than you can determine each cell size and insets using the following methods:

func collectionView(_ collectionView: UICollectionView, 
                      layout collectionViewLayout: UICollectionViewLayout, 
           insetForSectionAt section: Int) -> UIEdgeInsets

func collectionView(UICollectionView, layout: UICollectionViewLayout, sizeForItemAt: IndexPath) -> CGSize

func collectionView(UICollectionView, layout: UICollectionViewLayout, minimumLineSpacingForSectionAt: Int) -> CGFloat

First problem will appear when you will try to build Section 3. For that case I suggest you to search for "Waterfall layout", there are implementations on GitHub. When you will figure out how it works, you should do the following:

  1. Create UICollectionView
  2. Create UICollectionViewFlowLayout subclass
  3. Set your layout subclass as a collection view layout.
  4. For Sections 0-2 use plain UICollectionViewFlowLayout possibilities.
  5. For Sections like section 4 you should override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? and calculate attributes manually.

Sorry, if my answer is too broad.

Here are some useful links:

  • CollectionView programming guide
  • Waterfall layout
like image 147
fewlinesofcode Avatar answered Oct 11 '22 00:10

fewlinesofcode