UI Part 2 (UICollectionView Part 1)
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
- Create a
UICollectionView
object either through Interface Builder or from code and added as a subview to your view. - Provide the Layout Class which is subclass of
UICollectionViewLayout
. This class is very important otherwise you can’t create aUICollectionView
. The layout object is responsible for defining the organisation and location of all cells and supplementary views inside the collection view - 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 theUICollectionViewCell
class that your data source configures and provides
Example 1 : Image Gallery App
As shown in Figure 1 we did a few things
- Created a
collectionView
object and as mentioned previously we can’t initialise it without providing its layout object. In this case we usedUICollectionViewFlowLayout
which we will talk later in details - Created constraints and added it to the subview
- 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.
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.
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
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
- Use
UICollectionViewFlowLayout
concrete class, that provides default layout configuration - You can subclass
UICollectionViewFlowLayout.
If you want to add some new behaviour to existingUICollectionViewFlowLayout class
- You can subclass
UICollectionViewLayout
and implement all logic yourself - 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
- 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.
- You can create grid based layout very easily.
- Can have optional header and footer view section
- Can scroll vertically or horizontally
Properties Of UICollectionViewFlowLayout
- 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
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
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
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
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
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.
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
As shown in Figure 11 our gallery app now showing header and footer view. Few things to note
- You can have only one header/footer view per section
minimumLineSpacing
not apply to supplementary views
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
- Collection View composed of sections
- Sections composed of header/footer views and cells
- Cell represent the data and should be subclass from UICollectionViewCell that display actual unit of content. Here cell is image
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
sectionInset
specifies the distance between header and content and content and footers. But not between footer of section 0 and header of section 1,- There’s no such thing as “interSectionSpacing”,
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
width_minus_section_insets
→ we get the width of the collection view after removing left and right section insetsinterspacing
→ this is very important , because when you have 1 image to show per row you don’t haveminimumInteritemSpacing
, if you 2 images to show per row you have to subtractminimumInteritemSpacing
one time. So the series is we need to subtract (imagesPerRow — 1
) timesminimumInteritemSpacing
per row which means for every row we need to skip one time, So when multiple ofimagesPerRow
index came I didn’t considerminimumInteritemSpacing.
Note: Don’t use direct minimumInteritemSpacing
property or other from layout object in sizeForItemAt
because at that time it might not set
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
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
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)