UI Part 2 (UICollectionView Part 1)

Ali Akhtar
12 min readMay 27, 2020

--

https://developer.apple.com/documentation/uikit/uicollectionview

An object that manages an ordered collection of data items and presents them using customizable layouts. When adding a collection view to your user interface, your app’s main job is to manage the data associated with that collection view and tell collection View how to layout your data .

Steps to integrate UICollectionView into your application

  1. Create a UICollectionView object either through Interface Builder or from code and added as a subview to your view.
  2. Provide the Layout Class which is subclass of UICollectionViewLayout. This class is very important otherwise you can’t create a UICollectionView. The layout object is responsible for defining the organisation and location of all cells and supplementary views inside the collection view
  3. Provide the datasource object. The collection view gets its data from the data source object, which is an object that conforms to the UICollectionViewDataSource Protocol and is provided by your app. Data in the collection view is organised into individual items, which can then be grouped into sections for presentation. An item is the smallest unit of data you want to present. For example, in a photos app, an item might be a single image. The collection view presents items onscreen using a cell, which is an instance of the UICollectionViewCell class that your data source configures and provides

Example 1 : Image Gallery App

As shown in Figure 1 we did a few things

  1. Created a collectionView object and as mentioned previously we can’t initialise it without providing its layout object. In this case we used UICollectionViewFlowLayout which we will talk later in details
  2. Created constraints and added it to the subview
  3. Registered Custom Collection View cell which contains the imageView. Data in the collection view is organized into individual items, which can then be grouped into sections for presentation. An item is the smallest unit of data you want to present. For example, in a photos app, an item might be a single image. The collection view presents items onscreen using a cell, which is an instance of the UICollectionViewCell class that your data source configures and provides.
Figure 1

As we discussed earlier one of the responsibility of the developer is to provide data to collection view and in Figure 2 we provided collection view its data source by conforming to UICollectionViewDataSource protocol.

Figure 2

Run the application and you will see image gallery. As we said we need to provide datasource and layout object and it will do its work. DataSource we provided by conforming to UICollectionViewDataSource and provided each data for the cell. Layout object we provided when we initlizating the collection view by passing it to the UICollectionViewFlowLayout() instance which is the concrete class provided by apple

Figure 3

What is Layout Object

As previous, we need to create first layout objects that decide cell position, size and it’s location. The layout object should have classUICollectionViewLayout.

UICollectionViewLayout itself is an abstract class whose job is to determine the placement of cells and supplementary views. You can’t use this class directly though, you need to create subclass that provide much of that information. There are four ways you can create layout objects

  1. Use UICollectionViewFlowLayout concrete class, that provides default layout configuration
  2. You can subclass UICollectionViewFlowLayout. If you want to add some new behaviour to existing UICollectionViewFlowLayout class
  3. You can subclass UICollectionViewLayout and implement all logic yourself
  4. You can use Compositional layouts which is new and only available from iOS 13, which I think will replace UITableView completely in future

In our previous example we use UICollectionViewFlowLayout concrete class

UICollectionViewFlowLayout

  1. It implements the line breaking based layout which means the layout object places cells on a straight line or a linear path and fits as many cells as it can be along the line until it runs out of space. When it does it creates a new line and continues the layout process.
  2. You can create grid based layout very easily.
  3. Can have optional header and footer view section
  4. Can scroll vertically or horizontally

Properties Of UICollectionViewFlowLayout

  1. itemSize → The default size to use for cells. The default size value is (50.0, 50.0).

As shown in Figure 4.1 and 4.2 we change the itemSize property and now cell height and width changes to 300 by 300, previously it was using the default value . Note : itemSize is the property specific to UICollectionViewFlowLayout object. It uses this property to find the size of the cell and content size of the scrolling content area

Figure 4.1
Figure 4.2

What if we dynamically adjust the sizes based on the cell’s content and our data is changing frequently. The good news is UICollectionViewFlowLayout has delegate object that ask you to give size for each item, as shown in Figure 5

Figure 5

2. scrollDirection The scroll direction of the grid.The default value of this property is UICollectionView.ScrollDirection.vertical.The grid layout scrolls along one axis only, either horizontally or vertically.

Previously our scrolling direction is vertical which means its width is fixed and its height depends on the content. It starts with first row and tries to fill cell until it until it runs out of space. When it does it create new line and continues layout process

As shown in Figure 6 we changed the layout direction to horizontal which means its height is fixed and its width depends on the content. It starts with first column and tries to fill cell until it until it runs out of space (reaches screen height). When it does it create new column and continues layout process. Note: We also change the width of the cell to screen width using collection view bounds property

Figure 6
Figure 6

3. minimumLineSpacing → The minimum spacing to use between lines of items in the grid. The default value of this property is 10.0. For collection View having. his spacing is not applied to the space between the header and the first line or between the last line and the footer.

scrollDirection: horizontal this value represents the minimum spacing between successive columns.

scrollDirection: vertical this value represents the minimum spacing between successive rows

Let’s understand what is mean by minimum. As shown in Figure 7 , we didn't use the minimumLineSpacing default value. Instead we explicitly define value using minimumLineSpacingForSectionAt flowlayoutDelegate object, you can also assign this value when creating a layout object as well . Since the scrolling direction is vertical → It will be minimum spacing between successive rows, but since cell at index 0 has larger height and it follows the line spacing exactly 20 but other cells in this row has lower height in this line thus not follows 20 spacing their line spacing value is greater than 20.0 that’s why they name it as minimumLineSpacing (means minimum it follows this distance but this is not a guarantee). This is limitation of UICollectionViewFlowLayout

Figure 7

3. minimumInteritemSpacing → The minimum spacing to use between lines of items in the grid. The default value of this property is 10.0. For collection View having. This spacing is used to compute how many items can fit in a single line, but after the number of items is determined, the actual spacing may possibly be adjusted upward.

scrollDirection: horizontal this value represents the minimum spacing between items in the same column

scrollDirection: vertical this value represents the minimum spacing between items in the same row.

As shown in Figure 8 since scroll direction is vertical , the minimumInteritemSpacing will be the space between items in the same row. As you can the spacing bwteen items in row is 38 which is higher than we define that’s why it is called minimum. Question is how it calculates , I am not taking some point into account to make it simple

width_of_the_screen = 376
width_of_each_cell = 100
no_of_cell_can_be_shown_in_this_width = (376/100) 3.76 (3)
total_space_taking_by_three_cell = 300
remaing_spacing = 76
minimumInteritemSpacing = 76 / 2 = 38
Figure 8

Supplementary Views

If you have extra information you need to display that shouldn’t be in the cells but still somewhere within the collection view, you should use supplementary views. . Here the header and footer views can be referred as the supplementary views of the flow layout. By default, these views are disabled in the flow layout

Each section in a flow layout can have its own custom header and footer. To configure the header or footer for a view, you must configure the size of the header or footer to be non zero. You can do this by implementing the appropriate delegate methods or by assigning appropriate values to the headerReferenceSize and footerReferenceSize properties. If the header or footer size is 0, the corresponding view is not added to the collection view

As shown in Figure 9 we created Custom header and footer view. Make sure it should subclass UICollectionReusableView.

A UICollectionReusableView that defines the behavior for all cells and supplementary views presented by a collection view.Reusable views are so named because the collection view places them on a reuse queue rather than deleting them when they are scrolled out of the visible bounds. Such a view can then be retrieved and repurposed for a different set of content.

Figure 9

When the collection view first loads its content, it asks its data source to provide a view for each visible item. To simplify the creation process for your code, the collection view requires that you always dequeue views, rather than create them explicitly in your code and as shown in Figure 10.1 we are dequeue view by conforming to UICollectionViewDataSource protocol methoddequeueReusableSupplementaryView(ofKind:withReuseIdentifier: Also we provide size of our header and footer by conforming to referenceSizeForHeaderInSection and referenceSizeForFooterInSection method of protocol UICollectionViewDelegateFlowLayout, this will simply assign value to headerReferenceSize and footerReferenceSize property in UICollectionViewFlowLayout

headerReferenceSize , footerReferenceSize. → These are the properties in flowlayout object that track the footer and header position and logic wether to show header/footer view. It get set when you implement referenceSizeForHeaderInSection and referenceSizeForFooterInSection methods. You can manually set these values as well without implement delegate methods. The default size values are (0, 0). Collection View uses these to decide the height (if direction is vertical scrolling ,in this case width should be the same as collection view ) and width (if direction is Horizontal scrolling, in this case height would be same as height of the collection View) of header or footer view respectively. If the size in the appropriate scrolling dimension is 0, no footer/header is added.

Note: We are not taking section index into account because currently we are dealing with only one section

Figure 10.1
Figure 10.2

As shown in Figure 11 our gallery app now showing header and footer view. Few things to note

  1. You can have only one header/footer view per section
  2. minimumLineSpacing not apply to supplementary views
Figure 11

Working With Multiple Sections

As shown in Figure 12 we created two sections, Note annotated yellow rectangle represents complete section, so here is the conclusion

  1. Collection View composed of sections
  2. Sections composed of header/footer views and cells
  3. Cell represent the data and should be subclass from UICollectionViewCell that display actual unit of content. Here cell is image
Figure 12

4. sectionInset → The margins used to lay out content in a section. The default edge insets are all set to 0.

As shown in Figure 13 we added section insets to the content inside the section. Few things to note

  1. sectionInset specifies the distance between header and content and content and footers. But not between footer of section 0 and header of section 1,
  2. There’s no such thing as “interSectionSpacing”,
Figure 13

Example 2: Control Images Per Row

If you want to show the specify number of Images per row , you can do this as well. As shown in Figure 14 we created a cell width and height based on the available width we have . Lets’ understand it

  1. width_minus_section_insets → we get the width of the collection view after removing left and right section insets
  2. interspacing → this is very important , because when you have 1 image to show per row you don’t have minimumInteritemSpacing , if you 2 images to show per row you have to subtract minimumInteritemSpacing one time. So the series is we need to subtract (imagesPerRow — 1) times minimumInteritemSpacing per row which means for every row we need to skip one time, So when multiple of imagesPerRow index came I didn’t consider minimumInteritemSpacing.

Note: Don’t use direct minimumInteritemSpacing property or other from layout object in sizeForItemAt because at that time it might not set

Figure 14

Example 3 : Images Gallery With Horizontal Paging

As shown in Figure 15 we created horizontal collection view gallery in which there is no sectionInset, minimumInteritemSpacing , minimumLineSpacing and we only showing one image per page

Figure 15

But we have one problem , user have full control on scrolling and user can stop scrolling in which our screen is showing 50% data of page 1 and 50% of page 2. So we need to stop user not to be in that state

At this line only while creating a collection View.

isPagingEnabled → A Boolean value that determines whether paging is enabled for the scroll view. If the value of this property is true, the scroll view stops on multiples of the scroll view’s bounds when the user scrolls. The default value is false. It will not allow user to be in that state. Let’s say user is in page 1 and scroll above 50% to the page 2 then stops the scrolling this will automatically move the scrolling to page 2 as shown in Figure 16

collectionView.isPagingEnabled = true
Figure 16

Properties to Explore :

bounces → A Boolean value that controls whether the scroll view bounces past the edge of content and back again. If the value of this property is true, the scroll view bounces when it encounters a boundary of the content. Bouncing visually indicates that scrolling has reached an edge of the content. If the value is false, scrolling stops immediately at the content boundary without bouncing. The default value is true.

alwaysBounceVertical → default NO. if YES and bounces is YES, even if content is smaller than bounds, allow drag vertically

showsHorizontalScrollIndicator → default YES. show indicator while we are tracking. fades out after tracking .

decelerationRate → A floating-point value that determines the rate of deceleration after the user lifts their finger. Your application can use the normal and fast constants as reference points for reasonable deceleration rates.

Radio and Multiple Selection Collection

If you want to create single selection / multiple selection collection list . These properties will be helpful

allowsMultipleSelection, indexPathsForSelectedItems,

For more information see UIScrollView and UICollectionView documentation

Next Part

In the next part I cover how to subclass UICollectionViewFlowLayout and extend its behaviour even more. (Highly recommended)

Useful links

--

--

Ali Akhtar
Ali Akhtar

Written by Ali Akhtar

Senior iOS Engineer | HungerStation | Delivery Hero

No responses yet