<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Aleksej Gurin on Medium]]></title>
        <description><![CDATA[Stories by Aleksej Gurin on Medium]]></description>
        <link>https://medium.com/@dn070287gav?source=rss-8d86f952f545------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*4MC5SynU9eHSAwKl</url>
            <title>Stories by Aleksej Gurin on Medium</title>
            <link>https://medium.com/@dn070287gav?source=rss-8d86f952f545------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 29 Apr 2026 18:18:12 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@dn070287gav/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[How to build complex layout using UICollectionViewCompositionalLayout and…]]></title>
            <link>https://medium.com/@dn070287gav/how-to-build-complex-layout-using-uicollectionviewcompositionallayout-and-9448b11dcbee?source=rss-8d86f952f545------2</link>
            <guid isPermaLink="false">https://medium.com/p/9448b11dcbee</guid>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <dc:creator><![CDATA[Aleksej Gurin]]></dc:creator>
            <pubDate>Mon, 07 Oct 2019 14:57:47 GMT</pubDate>
            <atom:updated>2019-10-07T14:58:27.362Z</atom:updated>
            <content:encoded><![CDATA[<h3>How to build complex layout using <em>UICollectionViewCompositionalLayout and UICollectionViewDiffableDataSource</em></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Hs76rpk2uWg4PbqjuAx3Og.gif" /></figure><p>In the <a href="https://medium.com/flawless-app-stories/all-what-you-need-to-know-about-uicollectionviewcompositionallayout-f3b2f590bdbe">first</a> and the <a href="https://medium.com/flawless-app-stories/how-to-use-uicollectionviewdiffabledatasource-55c60e9d3897">second</a> article, I looked at how to work with <em>UICollectionViewCompositionalLayout</em> and <em>UICollectionViewDiffableDataSource</em>. They are the main components for <strong>UICollectionView. </strong>But all of this is just a theory, how to use them in practice? How to build a complex layout with them?</p><p>This is what I will explain in this article. My solution is not universal, but using it I have handled all the requirements I came up with.</p><p>Let’s imagine that we have a library, our goal is to build a mobile app in which library clients can take and return books. In this mobile application we will have three sections:</p><ol><li>Information about a client</li><li>Client books list</li><li>Library books list</li></ol><p>In the end, the application will look like at the screenshot</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tEd7zv_jVQmPAukIeBCyuw.png" /></figure><p>Before starting developing our sections, I need to resolve one problem. From the screenshot, you can see that in different sections we have different objects and they have a different layout. With<em> UICollectionViewDiffableDataSource</em> we can’t do that, that’s why I will build a wrapper and it will help us.</p><p>I want to use just structures, this will be a small experiment for me, with them it will be easier to implement a Hashable protocol, but harder to store them.</p><h3>Section &amp; Cell</h3><p>For a start let’s create two basic objects for our application. First will be a simple protocol <em>Cell,</em> this protocol will be implemented by our collection view cells. Inside it will have only one function, this function will be called by section and will configure a cell. Also, it will have an <em>associatedtype </em>Object, which will be passed in that function.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d7281b63b5e23608ad991e89cd4402ca/href">https://medium.com/media/d7281b63b5e23608ad991e89cd4402ca/href</a></iframe><p>Second object is an abstract class <em>Section, </em>it will implement a Hashable protocol and this class helps us to have the common behavior for all future sections.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8542b42d0bf6afd87cca9906375e8c33/href">https://medium.com/media/8542b42d0bf6afd87cca9906375e8c33/href</a></iframe><h3>CollectionAdapter</h3><p><em>CollectionAdapter </em>is a class, it will handle our two crucial objects <em>UICollectionViewCompositionalLayout</em> and <em>UICollectionViewDiffableDataSource. </em>This adapter will store UICollectionViewDiffableDataSource and will ask for snapshots data from its delegate. As we decided in sections, we will have different elements, that’s why will use the AnyHashable structure.</p><p>The delegate will have two simple methods, the first will return all sections to our collection, second will return elements for the section. Section will provide cells for the data source, that’s why we should add a function to it.</p><p>Working with <em>UICollectionViewCompositionalLayout</em> is much more simple, all we have to provide is how elements will layout in the sections. In order to do this, the section must have an additional function that will return this information.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/175f59b22b50d0dc8c764bcf78bbe790/href">https://medium.com/media/175f59b22b50d0dc8c764bcf78bbe790/href</a></iframe><p>One more important function we must add to our adapter is the one that will create snapshots and send them to the datasource using the <strong>apply</strong> method. Also before that, it must register cells in a collection. ViewController will be the delegate for our adapter and will return al thel needed data. Below you can find the code for this function.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/efdeffe1bd32defee0d8be79b206281e/href">https://medium.com/media/efdeffe1bd32defee0d8be79b206281e/href</a></iframe><h3>CollectionSection</h3><p>I have decided that in <strong>one</strong> section I will have only <strong>one</strong> kind of elements. With this let me introduce to you a generic section class which I will use for sections — <em>CollectionSection</em>. This class will have two generic elements, first will be our element and second — a cell for it. This class will inherit from the Section class and will return cells and layout for our adapter.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/07ece9a57633050e3298818e514d79a4/href">https://medium.com/media/07ece9a57633050e3298818e514d79a4/href</a></iframe><h3>Client Section</h3><p>Regarding our requirements in this section we should have short information about the client and amount of books he has taken. So we need a cell and a model.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/090a86a1e88549d925c551888a0d9ed4/href">https://medium.com/media/090a86a1e88549d925c551888a0d9ed4/href</a></iframe><p>After this we should configure our new section and return data for it from ViewController to the adapter.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f4089ccd1dc6e651ac6e9d76f93fbb4a/href">https://medium.com/media/f4089ccd1dc6e651ac6e9d76f93fbb4a/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rIuBxmzyqC9YkOEoDe5Dyg.png" /></figure><h3>Library Books Section</h3><p>Next, our section will be the section where we will show books in the library. This section will hold books and if we take one it will have a checkmark on it and also will be added to the client books section.</p><p>Cells in it will have dynamic height and grid layout. For taking and returning books we should define one method, this method will be called when we tap on the cell. It should be added to CollectionAdapter, Section, and CollectionSection.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c935925c44b03df797da7774a04768da/href">https://medium.com/media/c935925c44b03df797da7774a04768da/href</a></iframe><p>Next step is to implement this method inside ViewController</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c9cc4805859dcab148f74da0a4f15fd9/href">https://medium.com/media/c9cc4805859dcab148f74da0a4f15fd9/href</a></iframe><p>With this small amount of code we have two sections. And if a client takes some book we will see the change in the client section.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WGSX0iK5GWulvOA2fUFY3A.gif" /></figure><h3>Client Books Section</h3><p>In this section will be books which client have taken from the library, the section should have horizontal scrolling and if we tap on the return button in the cell, the book should be returned to the library.</p><p>Two interesting requirement we should cover here. First, we have to have an empty view which will show that we don’t have any books at a client home. For this requirement I have decided to use the supplementary view, using <em>UICollectionViewCompositionalLayout</em> we can put it inside the section and it will take the whole section size. <em>UICollectionViewCompositionalLayout</em> is pretty smart and will draw the empty view even if it has no elements inside.</p><p>I will create a separate section, it will inherit from <em>ClientBooksSection</em>, this section can return a supplementary view for the collection and will show it only if the section doesn’t have elements. Section will know about that from the adapter.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/54b2ba492a54251b8deb47e736d0ee59/href">https://medium.com/media/54b2ba492a54251b8deb47e736d0ee59/href</a></iframe><p>Second, add additional configuration to the cell, it is because ViewController will be the delegate for the cell and react when user taps on the return button, after that a book will be returned to the library.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/61bd5e0cc817b9b7943a68a034474804/href">https://medium.com/media/61bd5e0cc817b9b7943a68a034474804/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nNp09fGlp-r__zHW4A3F5Q.gif" /></figure><h3>Summary</h3><p>The bottom line for all three articles is — Apple did what they should have done a long time ago, it gives us instruments that will help in the collection development, this is good, but it is bad that it is a little bit late. As soon as you stop supporting iOS 12 you can do refactoring for your old collections using these new instruments. Full project source code you can find at <a href="https://github.com/IceFloe/ComplexUICollectionLayout">Github</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9448b11dcbee" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to use UICollectionViewDiffableDataSource]]></title>
            <link>https://medium.com/@dn070287gav/how-to-use-uicollectionviewdiffabledatasource-55c60e9d3897?source=rss-8d86f952f545------2</link>
            <guid isPermaLink="false">https://medium.com/p/55c60e9d3897</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[mobile]]></category>
            <dc:creator><![CDATA[Aleksej Gurin]]></dc:creator>
            <pubDate>Fri, 20 Sep 2019 10:55:28 GMT</pubDate>
            <atom:updated>2019-09-20T10:56:05.642Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nplSi6UQsiyThqBJymN-cg.gif" /></figure><p>In the <a href="https://medium.com/flawless-app-stories/all-what-you-need-to-know-about-uicollectionviewcompositionallayout-f3b2f590bdbe">last article</a>, I shared my investigation of <em>UICollectionViewCompositionalLayout.</em> But all experienced developers know that <em>UICollectionView</em> contains two parts — Layout and Datasource. In this article, I will look at the second part, the instrument which also was introduced at the last WWDC — <em>UICollectionViewDiffableDataSource.</em></p><p>If you have ever heard or read about the <a href="https://github.com/Instagram/IGListKit">IGListKit</a>, then <em>UICollectionViewDiffableDataSource</em> will also look familiar to you, as usual, Apple took some idea and presented their solution.</p><p>In this solution you can find two classes, they are doing all heavy lifting work for you — <em>UICollectionViewDiffableDataSource</em> and <em>NSDiffableDataSourceSnapshot</em>, they are both generic and tightly coupled.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cfa0b8617b2be16fe4703f5fc89eafce/href">https://medium.com/media/cfa0b8617b2be16fe4703f5fc89eafce/href</a></iframe><h3>UICollectionViewDiffableDataSource</h3><p>The main goal for this class is to prepare all the needed data for UICollectionView. It is initialized with closure, this closure has to provide cells for the collection. In addition, you can find optional closure which could provide <em>Supplementary View.</em></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b2954097386976fe642baacdb9be0069/href">https://medium.com/media/b2954097386976fe642baacdb9be0069/href</a></iframe><p>Also, this class can take <em>NSDiffableDataSourceSnapshot,</em> this is the snapshot of your datasource data, at first it will save its copy, for the second time, it will find the difference between saved copy and new snapshot and apply it to the UICollectionView automatically.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ae61b889c903ae0efb7cc987dddbe6f8/href">https://medium.com/media/ae61b889c903ae0efb7cc987dddbe6f8/href</a></iframe><p>Let’s remember what we had before this nice update. We had an object, it had all our data and provided this data to a collection, this object implements <strong>UICollectionViewDataSource</strong>. It provided the number of sections, elements, cells for these elements, etc. If we had to insert, remove or move elements in a collection, we would find what changed in our data and then tell to a collection about it through these methods.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a00422e6f2cc3ed39a209237abfec778/href">https://medium.com/media/a00422e6f2cc3ed39a209237abfec778/href</a></iframe><p>After all of this, we had to call the method <strong>performBatchUpdates</strong> or tell nothing to a collection and just call <strong>reloadData</strong>. And a lot of programmers would choose the second option because of the two reasons:</p><ol><li>Sometimes it is really hard to find the difference between two arrays, for this, we should develop some algorithm.</li><li>Calling method performBatchUpdates you can see this very often.</li></ol><pre><strong>Invalid</strong> update: invalid number of items <strong>in</strong> section 0. <strong>The</strong> number of items contained <strong>in</strong> an existing section after the update (1) must be equal to the number of items contained <strong>in</strong> that section before the update (1), plus or minus the number of items inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved <strong>in</strong>, 0 moved out).</pre><p>If you start googling this error, you won’t find an answer fast, after some time you will probably understand what this error means that somewhere in your <em>UICollectionViewDataSource</em> data and in a collection data system has found the difference and can’t build a collection layout. Then you have to spend some time to find where it is and fix it.</p><p>To tell the truth, this is a kind of a nightmare for me, because I have used IGListKit for a long time, I don’t have a problem together with it :) Now we have a native solution with <em>UICollectionViewDiffableDataSource</em>, it can save your time and nerves. Everything is simplified, just tell it, that you have new data and after this, all changes will be done in the UICollectionView automatically and you will see your new cells with nice animation.</p><h3>NSDiffableDataSourceSnapshot</h3><p>This is a struct and a snapshot of your data, <em>UICollectionViewDiffableDataSource</em> is using this data. Snapshot has all methods for data manipulation like insert, move, delete, append, reload. All these methods are simple, I think even a newbie can understand how to use them. I will describe something that is hard to understand from the documentation.</p><p>So basically this structure holds two generic elements:</p><pre><strong>SectionIdentifierType</strong> : <strong>Hashable</strong><br><strong>ItemIdentifierType</strong> : <strong>Hashable</strong></pre><p>From the description, you can see that this is section and element identifiers, by “identifiers” they mean object or struct which implements Hashable protocol. This item identifiers will later be passed to the <em>UICollectionViewDiffableDataSource </em><strong>cellProvider </strong>closure. Section and elements identifiers don’t overlap each other, but also should be unique in the snapshot. If you had them twice or more, then datasource will show a warning in the logs.</p><p>In the snapshot must be at least one section, in the section you can add elements with two available options — with section identifier and without it.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ea56946495addec6cd291f8b06079833/href">https://medium.com/media/ea56946495addec6cd291f8b06079833/href</a></iframe><p>If you pass elements without section identifier, then they will be added to the last one.</p><p>Basically elements and sections have different places in a store, due to this you can move elements without saying to what section they should be moved.</p><p>One reminder about Hashable protocol, it is used for comparing elements in snapshots, when datasource receives a new snapshot, it will compare the current and the new snapshot. Structs are more convenient than classes in this situation because they automatically implement this protocol in the latest Swift. In the classes you have to implement it is by yourself.</p><p>You can use a snapshot in two ways. First, you can take a current snapshot from datasource and modify it.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f41203452975ad9cb82e0bb2ea850e00/href">https://medium.com/media/f41203452975ad9cb82e0bb2ea850e00/href</a></iframe><p>This is convenient if you have to reload cells and you did not implement Hashable for all your properties. With this we have one peculiarity, if you are using structs for elements identifiers, unfortunately, you can not reload them easily, they are value-based and to update them in the current snapshot you should do one trick. It would be convenient to have some kind of update method like in the Set but we don’t have it. Below you can find an example of how to update the struct in the snapshot.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/faac316bc55ecc7a4fbde481b6c2a3a6/href">https://medium.com/media/faac316bc55ecc7a4fbde481b6c2a3a6/href</a></iframe><p>If you are using classes you should not care about it, datasource will copy only references, that’s why you can change variables and reload an item inside a snapshot.</p><p>The second way, and personally I like it more, is to create a new snapshot from your data and pass it to the datasource using the <strong>apply </strong>method.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/20275b944bcade055663c077b96e05c2/href">https://medium.com/media/20275b944bcade055663c077b96e05c2/href</a></iframe><h3>Bonus</h3><p>I have found some additional features about <em>UICollectionViewDiffableDataSource</em> during researching and want to share them with you.</p><p>You can call <em>UICollectionViewDiffableDataSource</em> <strong>apply</strong> method in the background queue, in this case, it will calculate the difference inside that queue and then will call UICollectionView methods automatically in the main queue. You will probably need this when you have a lot of data and have some performance issues with it. One restriction here, you must call apply the method in the same queue always, or you will see warnings in the logs and maybe undefined behavior.</p><p>You can control animation time for the collection changes, just put apply the method in the animation block.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1e44964dc84294e1d12a37a9280500a2/href">https://medium.com/media/1e44964dc84294e1d12a37a9280500a2/href</a></iframe><p>And the last one, sooner or later you will ask yourself, how to use different items for different sections. <em>UICollectionViewDiffableDataSource</em> is a generic class and you can’t use Hashable protocol directly, only via specific classes, you should use additional techniques. I see at least two options.</p><p>You can use an associative enum:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f73269bd7e36dac480d1ced685b6c465/href">https://medium.com/media/f73269bd7e36dac480d1ced685b6c465/href</a></iframe><p>Or AnyHashable struct:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/89d824002bd2d11e708a9d35ca4c95bd/href">https://medium.com/media/89d824002bd2d11e708a9d35ca4c95bd/href</a></iframe><h3>Conclusion</h3><p>With UICollectionViewDiffableDataSource it is easier to develop collections and do updates on them. We don’t need to call additional methods and will reduce the number of errors which we can produce during the development.</p><p>In the next and the last article for this series, I will combine UICollectionViewDiffableDataSource and UICollectionViewCompositionalLayout and build a complex screen with a collection which will use them.</p><ol><li><a href="https://developer.apple.com/documentation/uikit/uicollectionviewdiffabledatasource">Documentation</a></li><li><a href="https://developer.apple.com/videos/play/wwdc2019/220/">Advances in UI Data Sources(WWDC)</a></li><li><a href="https://developer.apple.com/documentation/uikit/views_and_controls/collection_views/using_collection_view_compositional_layouts_and_diffable_data_sources">Using Collection View Compositional Layouts and Diffable Data Sources</a></li><li><a href="https://github.com/IceFloe/UICollectionViewDiffableDataSource">Github</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=55c60e9d3897" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[All what you need to know about UICollectionViewCompositionalLayout]]></title>
            <link>https://medium.com/@dn070287gav/all-what-you-need-to-know-about-uicollectionviewcompositionallayout-f3b2f590bdbe?source=rss-8d86f952f545------2</link>
            <guid isPermaLink="false">https://medium.com/p/f3b2f590bdbe</guid>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[mobile]]></category>
            <dc:creator><![CDATA[Aleksej Gurin]]></dc:creator>
            <pubDate>Tue, 03 Sep 2019 12:28:05 GMT</pubDate>
            <atom:updated>2019-09-06T18:51:38.998Z</atom:updated>
            <content:encoded><![CDATA[<h3>All you need to know about UICollectionViewCompositionalLayout</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sXYETUtZYV8q7lRfEljijQ.png" /><figcaption>Thanks to <a href="https://twitter.com/juanlaube">@juanlaube</a> for sharing his UICollectionViewCompositionalLayout tips, which became the inspiration for this cover</figcaption></figure><p>In the current year, Apple showed mind-blowing conference WWDC to us. All iOS dev community are focusing on new cool frameworks and features(SwiftUI, Combine, RealityKit, etc.) trying to figure out how they are working and what to do with them. Many other small but very helpful for current applications features somehow stayed off the screen and today I want to share my own research about one of them — <strong><em>UICollectionViewCompositionalLayout</em></strong>.</p><p>I am pretty sure that every newbie iOS developer has started his learning path from the list view, this is a crucial UI element you can find almost in all applications. <em>UICollectionView </em>evolved from <em>UITableView, </em>this fancy UI element helps us to put items in a different order on the screen, all that we have to do is to use <em>UICollectionViewFlowLayout </em>or create a custom one extending <em>UICollectionViewLayout.</em></p><p>But stop! Have you ever tried to do that? If you have you know how hard this is, there is a bunch of different methods, we have to use to create a nice behavior, later on, you would figure out that maybe you should add caching or something else.</p><p>All these hard things are stopping developers, they are lazy, they don’t want to do something like this and usually, they are trying to find some library which will help them. That’s why this year Apple gives us <em>UICollectionViewCompositionalLayout </em>and this class continues the era of declarative programming.</p><p><strong><em>UICollectionViewCompositionalLayout</em></strong> is a new fancy Layout, with it we can declaratively setup how it should display items in <em>UICollectionView</em>. After a little amount of code layout will understand what to do and will do all the hard work instead of us, with it you don’t have to implement any of those methods from <em>UICollectionViewLayout!</em></p><p>Let’s look at a simple example the code below will create a list in which all the rows have the same absolute height.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a492d507741e4ab530f03d919e78ddd8/href">https://medium.com/media/a492d507741e4ab530f03d919e78ddd8/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/369/1*Dbs-7d97pb5O6oSDr5MuZw.png" /></figure><p>Our next step will be to look at all those classes which are involved in Layout creation.</p><h3>NSCollectionLayoutSize</h3><p>We should use <em>NSCollectionLayoutSize</em> for setting width and height of the item in Layout. It has two main variables which you should setup during initialization.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3efe1ea179ce467bc8102f3ce2fb77ad/href">https://medium.com/media/3efe1ea179ce467bc8102f3ce2fb77ad/href</a></iframe><p><em>NSCollectionLayoutDimension </em>has four variants</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e642d203ad066e262fa99d09583e138f/href">https://medium.com/media/e642d203ad066e262fa99d09583e138f/href</a></iframe><p>One interesting thing you can do with it, you can set in the <strong><em>NSCollectionLayoutSize.widthDimension NSCollectionLayoutDimension.fractionalHeight</em></strong><em> </em>and vice versa. For example <em>NSCollectionLayoutSize.heightDimension = .fractionalWidth(0.5) </em>means that the height of the item will be equal to half of the width group.</p><p><strong><em>Estimated</em></strong> is the most interesting and powerful one, it is calculating the size for the row “on the fly”. If you have tried to do it previously, you know that it does not work at all with complex cells. I have tested current implementation and it looks pretty good to me, I did not see any problems there at all. Only one thing you have to do is to set item and group <em>heightDimension</em> into type <em>estimated. </em>One restriction we have here is that you must not set <em>contentInsets </em>for element, otherwise Layout will warn you and won’t draw respectively.</p><p>In this example you will see Layout for the list where size for the elements is calculated during the rendering process.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/59907b8c9d8d64f39a5ac7702bb4c6ce/href">https://medium.com/media/59907b8c9d8d64f39a5ac7702bb4c6ce/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/369/1*it2y6Motxrx8cS5zs-Z0AQ.png" /></figure><h3>NSCollectionLayoutItem</h3><p><em>NSCollectionLayoutItem </em>is responsible for setting item in collection group, it’s initializing with <em>NSCollectionLayoutSize</em>. In this class you can find two variables which help setup insets and spacing.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3d162a1754a3d4edf74fa3d6a706a781/href">https://medium.com/media/3d162a1754a3d4edf74fa3d6a706a781/href</a></iframe><p><em>contentInsets </em>is working in this way: at first Layout calculates the place and size for the element, then it is looking for element insets in this variable. Like I said before, don’t use <em>contentInsets</em> with estimated size.</p><p><em>edgeSpacing </em>is much more interesting, this is the separate class <em>NSCollectionLayoutEdgeSpacing </em>inside which you can find the same variables as for insets(leading, top, trailing, bottom) but you must use the separate class <em>NSCollectionLayoutSpacing</em> there, not just simple float variable. This spacing is used by Layout before calculating the place for the items, you can use it for filling empty space in your Layout. You can find two types of spacing in the class</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/60108f8bf5de38c27dcc252a21e6bc41/href">https://medium.com/media/60108f8bf5de38c27dcc252a21e6bc41/href</a></iframe><p><strong><em>flexible</em></strong><em> </em>is for filling empty space which we have in a group</p><p><strong><em>fixed</em></strong> is doing what it is saying, sets fixed spacing</p><p>As an example I will create Layout where with <em>edgeSpacing </em>two columns will be placed in the middle of the screen.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/616feee34d4ccb3559812a782503edfd/href">https://medium.com/media/616feee34d4ccb3559812a782503edfd/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/369/1*Zj9LvYkT3pwoCzpKBcQZTg.png" /></figure><h3>NSCollectionLayoutGroup</h3><p><em>NSCollectionLayoutGroup </em>extending <em>NSCollectionLayoutItem</em>. It adds a crucial feature, you can add there as many items as you want to. Section must have only one group, then during rendering process Layout will draw groups depending on how many items we have in the datasource. For example we have one group, and in it we have one element, datasource is “saying” that we have ten items, than ten groups will be drawn, if we have 2 items in a group then 5 groups will be drawn. Groups can be visualized like stacks, they can be vertical or horizontal, you can add there one kind of item or more. If you want to set some space between items you can use <em>interItemSpacing</em> variable.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4ad53a6cef411f8c27d2eaa436689e5b/href">https://medium.com/media/4ad53a6cef411f8c27d2eaa436689e5b/href</a></iframe><p>If you don’t like vertical and horizontal groups, then you can create your own custom variant.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ca77a3038a063ba02e35eca34ca074a5/href">https://medium.com/media/ca77a3038a063ba02e35eca34ca074a5/href</a></iframe><p>With <em>NSCollectionLayoutGroupCustomItem</em> class you can set object position in the group, also you can use zIndex if needed. In closure <em>NSCollectionLayoutGroupCustomItemProvider</em> we will receive <em>NSCollectionLayoutEnvironment</em>, it contains container size and also its trait collection.</p><p><strong>The most important thing</strong> is that you can put a group in a group, like in a stack. That’s because group extends <em>NSCollectionLayoutItem</em>. Using this cool feature I have created complex layout with multiple groups.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/be838600e742783dec5d85f94da4a93e/href">https://medium.com/media/be838600e742783dec5d85f94da4a93e/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/369/1*-mimSSotfrSNMl2-V6bKbw.png" /></figure><h3>NSCollectionLayoutSection</h3><p>After looking at all previous section components, I think you should not have any questions about it. Section is the place where we can have one or more groups, groups can have one or more items. Here we can also set additional spacing for groups and for all content.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8f82644905bd991795f3e51a48903fb9/href">https://medium.com/media/8f82644905bd991795f3e51a48903fb9/href</a></iframe><p>In addition we have two interesting variables here.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0d12ee2f4adc0445cfa0d1de6ba2ceb8/href">https://medium.com/media/0d12ee2f4adc0445cfa0d1de6ba2ceb8/href</a></iframe><p><em>visibleItemsInvalidationHandler </em>— this closure is called before each rendering cycle, you can use it if you want to know what items are currently visible on the screen, change this items layout or know what offset we currently have.</p><p><em>orthogonalScrollingBehavior </em>— with this variable you can set opposite scroll for particular section. If you have ever tried to do that, you know that the simplest way was to put one more collection in the cell, but from the architecture perspective that was really awful. I think this is what we were waiting for for a long time. We have FIVE different scroll behaviours.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/296e5e508204a24a0f1357a02f2304dd/href">https://medium.com/media/296e5e508204a24a0f1357a02f2304dd/href</a></iframe><p>In the next example you can see how <em>continuous </em>type is working, this is amazing!</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6b7a7480c6ab2663ea0ac91167e39588/href">https://medium.com/media/6b7a7480c6ab2663ea0ac91167e39588/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/388/1*cuUWZS-5lDntCutsOOXzJQ.gif" /></figure><h3>UICollectionViewCompositionalLayout</h3><p><em>UICollectionViewCompositionalLayout </em>is our main class, we can initialize it with <em>NSCollectionLayoutSection </em>or with closure, this closure will be called when layout needs information about the section, here you can set up different behaviour for different sections depending on container size and trait collection, portrait and landscape type. Using <em>UICollectionViewCompositionalLayoutConfiguration</em>, you can set scroll direction and space between sections.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d7156ac8ccb7c7e0b849cdfa3b98a29b/href">https://medium.com/media/d7156ac8ccb7c7e0b849cdfa3b98a29b/href</a></iframe><h3>NSCollectionLayoutSupplementaryItem, NSCollectionLayoutBoundarySupplementaryItem, NSCollectionLayoutDecorationItem</h3><p>I keep silence about this additional items intentionally because we are not using them in full power usually, but with this new layout system it will be much easier. I will briefly touch all of them and will show examples with them.</p><p><em>NSCollectionLayoutSupplementaryItem </em>is used for items and groups<em>. </em>The key difference here is how we should add this item to layout. For this we have separate class <em>NSCollectionLayoutAnchor</em>, this item is always rendering above the main element(group, item), that’s why we anchor it to the item sides. It is sounds complicated but on practice it is quite easy. Here is Apple doc example</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4e293211cdc4a3ad4486206c46035fb5/href">https://medium.com/media/4e293211cdc4a3ad4486206c46035fb5/href</a></iframe><p>In addition we can specify absolute or fractional offset. The Fractional one is based on the item size.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/be65d69276303a95f120aba8bed7785f/href">https://medium.com/media/be65d69276303a95f120aba8bed7785f/href</a></iframe><p>Here is my Layout example where I put a checkmark on a group</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5e2d1674625d84d0962e194f4fadd9c2/href">https://medium.com/media/5e2d1674625d84d0962e194f4fadd9c2/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/369/1*0cRRFT6hIZ2TnhFGShgGfA.png" /></figure><p><em>NSCollectionLayoutBoundarySupplementaryItem </em>— this footers and headers, we all know them, right? This item you can add to <em>NSCollectionLayoutSection</em> and <em>UICollectionViewCompositionalLayoutConfiguration. </em>The size you can set with <em>NSCollectionLayoutSize</em>, and where the item will be — with <em>NSRectAlignment</em>. For header you should set <em>NSRectAlignment </em>to .top, for footer — equals to .bottom.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/da005764a87423932fb38065016fb988/href">https://medium.com/media/da005764a87423932fb38065016fb988/href</a></iframe><p>One interesting variable we have — <em>pinToVisibleBounds</em>, we can do a “sticky header/footer” with it. If you set it in true then current item will be visible whenever its section is visible.</p><p>In the example I create three items, at the top, left and bottom, one thing I want to note is that fractional size for this item is based on container not on the section, that’s why left item size you can not set as fractional, you should calculate your section size and set it in absolute value. Maybe in release Apple will change that.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/743797cd584ee57d9bcd480c40f95705/href">https://medium.com/media/743797cd584ee57d9bcd480c40f95705/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/369/1*G1Ml_X7HZoT0YSQLmsMMZw.png" /></figure><p>And the last thing is <em>NSCollectionLayoutDecorationItem, </em>with it we can set background for section, it is easy to use and has only one static initializer.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/208b97ca35e9cf34f2d3cb42d9e25e5b/href">https://medium.com/media/208b97ca35e9cf34f2d3cb42d9e25e5b/href</a></iframe><p>This item extends from <em>NSCollectionLayoutItem,</em> that’s why we can set <em>contentInsets</em> for it, with insets you can adjust bounds for the background. One more specific thing for this item, you must register it in <em>UICollectionViewCompositionalLayout</em>.</p><p>In the example, I add shadow for the whole section which is quite cool.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1cbfaa016931230233f639cbc6ea838d/href">https://medium.com/media/1cbfaa016931230233f639cbc6ea838d/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/369/1*CiOqflAIWXUJFxGDldYaWg.png" /></figure><h3>Conclusion</h3><p><em>UICollectionViewCompositionalLayout </em>is one of the big steps in iOS development, with this tool it is much easier to create the collection of elements, declarative behavior will satisfy 99% developers.</p><p>While the SwiftUI is still in active development and there we still don’t have collections at all, I highly recommend using this new Layout in new projects. In the next article, I will try to experiment with <em>UICollectionViewDiffableDataSource</em>.</p><ol><li><a href="https://developer.apple.com/documentation/uikit/views_and_controls/collection_views/compositional_layout_objects">Documentation</a></li><li><a href="https://developer.apple.com/videos/play/wwdc2019/215/">Advances in Collection View Layout(WWDC)</a></li><li><a href="https://developer.apple.com/documentation/uikit/views_and_controls/collection_views/using_collection_view_compositional_layouts_and_diffable_data_sources">Using Collection View Compositional Layouts and Diffable Data Sources</a></li><li><a href="https://github.com/IceFloe/UICollectionViewCompositionalLayout">Github</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f3b2f590bdbe" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>