Slide 1

Slide 1 text

Backporting Collection View Compositional Layouts Kishikawa Katsumi Hi! I'm Katsumi Kishikawa, an iOS engineer. Today, I'm excited to talk to you about collection view compositional layouts. It is a new API introduced iOS 13. It is an entirely new mechanism for building custom layouts for collection views. It's very powerful and flexible. You can easily make any layout without bugs. It's amazing. It just grabs my heart when I watched a session about it at WWDC. But this wonderful API is less known than I expected,

Slide 2

Slide 2 text

Agenda • What is Collection View Compositional Layouts? • What problem does it solve? • Anatomy: Compositional Layouts • Backporting Collection View Compositional Layouts So today, I'm going to share what the collection view compositional layout is. And I will talk about what problems that the old ways have so far, and how the new API will solve them. Then, I will explain how it works. And I wanted to use this wonderful API in production right away, so I ported it to iOS12 and older versions. So finally, I'm going to share some technique to backport it to earlier iOS 12. Let's get started.

Slide 3

Slide 3 text

What is Collection View Compositional Layouts? First, What is Collection View Compositional Layouts?

Slide 4

Slide 4 text

What is Collection View Compositional Layouts? • New API introduced by iOS 13 • Extremely easy to build custom complex collection view layouts • Powerful features to beat complex layouts for modern apps Collection view compositional layout is a new API introduced by iOS 13. It makes extremely easy to build custom layouts for collection views. It's a completely different approach, and it's easy to use and hard to mistake. Also, it has powerful features that make it easy to achieve complex behaviors that a modern app requires.

Slide 5

Slide 5 text

https://developer.apple.com/videos/play/wwdc2019/215/ WWDC 2019 In WWDC 2019, Apple says their own App Store app has been rearchitected using compositional layout.

Slide 6

Slide 6 text

https://developer.apple.com/videos/play/wwdc2019/215/ WWDC 2019 Thanks to compositional layout, he says that the codebase can be significantly simplified. Maintainability has improved. Also, his aspect of the collection view has completely changed.

Slide 7

Slide 7 text

Example: App Store.app So let's see the App Store app as an example.

Slide 8

Slide 8 text

Modern App UI is Complicated! • Various rich contents
 must be displayed • Various sizes of content are
 on a scroll view • Nested scrolling The App Store app has a typical modern app UI. The layout of this app is very complicated. Various sizes of content should be displayed, on a scroll view. Also, in most cases, nested scrolls are required. It looks cool when the scrolls are nested vertically and horizontally. It is making people think that the app is a cool modern app. So nesting scroll views orthogonally are often required to make your app look very modern and cool.

Slide 9

Slide 9 text

How to make it? • Collection View or
 Stack View with Scroll View? • Collection View on Collection View • Collection View Custom Layouts So how do we make a such UI? There are multiple solutions. For example, using multiple collection views? Stack view and scroll view? Or build custom collection view layouts? Each solution has trade-offs. Collection view on collection view is much simpler than building custom layouts. However, data management and reusing cells are dramatically more complicated. Building custom layouts seems right way, but I never want to do. Why?

Slide 10

Slide 10 text

Problem: Building Custom Collection View Layouts Because building custom layouts has a lot of problems. People who have made or people tried to make it may know. What are problems?

Slide 11

Slide 11 text

How to Build Custom Collection View Layouts • Subclass UICollectionViewLayout • Override methods as needed. What should I do to build custom collection view layouts? Subclassing UICollectionViewLayout. Then override methods as needed. That's it. It's a piece of cake! Right?

Slide 12

Slide 12 text

The problem Why difficult to build custom collection view layouts Unfortunately NO. I will explain what the problem with building custom layouts is and why I don't want to do it.

Slide 13

Slide 13 text

Why Difficult to Build Custom Collection View Layouts? • Implement everything yourself • I don't know where to start • Error prone • Too flexible, overkill To create a custom layout, subclass UICollectionViewLayout. But UICollectionViewLayout class is a very abstract class. So we have to implement everything ourselves. UICollectionViewLayout doesn't help anything to calculate the layout. There is just an empty method to override. You have to do all the layout calculations and prepare yourself.

Slide 14

Slide 14 text

UICollectionViewLayout class UICollectionViewLayout { class var layoutAttributesClass: AnyClass class var invalidationContextClass: AnyClass func prepare() func layoutAttributesForElements(in rect: CGRect) func layoutAttributesForItem(at indexPath: IndexPath) func layoutAttributesForSupplementaryView(ofKind: String, at: IndexPath) func layoutAttributesForDecorationView(ofKind: String, at: IndexPath) func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) func invalidationContext(forBoundsChange newBounds: CGRect) func shouldInvalidateLayout(forPreferredLayoutAttributes:, withOriginalAttributes:) func invalidationContext(forPreferredLayoutAttributes:, withOriginalAttributes:) func targetContentOffset(forProposedContentOffset: CGPoint, withScrollingVelocity: CGPoint) func targetContentOffset(forProposedContentOffset: CGPoint) var collectionViewContentSize: CGSize ... The code here is an example of the UICollectionViewLayout interface. It has many methods. Most people don't know where to start, what we should do. We don't know the right way, and it is error-prone. So we are forced to trial and error many times. Therefore, an implementation cost becomes too high. I'm pretty sure that is not what we wanted.

Slide 15

Slide 15 text

Easy Simple Complex Collection View on Collection View Custom Layouts Hard Flow Layout Layout Layout This figure very roughly shows the implementation costs of each solution. Also, the layout complexity that each solution can produce. So which way do we use? Collection View Flow layout can be used easily. But the range it covers is not big. It is difficult to build a complex layout using only that.

Slide 16

Slide 16 text

Easy Simple Complex Collection View on Collection View Custom Layouts Hard Flow Layout Implementation Layout Layout Other solution, the way of nesting collection views, called the collection view on collection view, can be used to build complex layouts. So most people tend to choose a way to nest collection views. Because another solution, building custom layouts are too early to use for us. However, it should become much more difficult; managing data sources and each scroll offset, UI event handling, and reusing cells become much more difficult.

Slide 17

Slide 17 text

Easy Simple Complex Collection View on Collection View Custom Layouts Hard Flow Layout Compositional Layouts Implementation Layout Layout Then the compositional layout appears this position! You can easily create any complex layout and easy to use. I even think that all views can be built with the compositional layouts.

Slide 18

Slide 18 text

Anatomy: Compositional Layouts Up next, to show that my opinion is correct, let's see how the compositional layout works.

Slide 19

Slide 19 text

App Store.app Let's go back to the App Store.app example. Please think; How long does it take time to develop these views? 2 weeks? One month? Using the compositional layout can be done in just 5, 6 hours.

Slide 20

Slide 20 text

I will explain how to build a layout. Let's see these three kinds of components as examples.

Slide 21

Slide 21 text

Layout, Section, Group, Item Anatomy: Compositional Layouts There are four important parts in the compositional layout, →

Slide 22

Slide 22 text

Layout, Section, Group, Item Anatomy: Compositional Layouts Layout, →

Slide 23

Slide 23 text

Layout, Section, Group, Item Anatomy: Compositional Layouts Section, →

Slide 24

Slide 24 text

Layout, Section, Group, Item Anatomy: Compositional Layouts Group →

Slide 25

Slide 25 text

Layout, Section, Group, Item Anatomy: Compositional Layouts and Item. Composing these four parts can produce any layout.

Slide 26

Slide 26 text

Layout, Section, Group, Item Layout There is a layout. There is only one layout as the outermost container.

Slide 27

Slide 27 text

Layout, Section, Group, Item Layout Section A layout can have multiple sections.

Slide 28

Slide 28 text

Layout, Section, Group, Item Section Layout →

Slide 29

Slide 29 text

Layout, Section, Group, Item Section Layout →

Slide 30

Slide 30 text

Layout, Section, Group, Item Layout Section Group Section has multiple groups.

Slide 31

Slide 31 text

Layout, Section, Group, Item Layout Section Group →

Slide 32

Slide 32 text

Layout, Section, Group, Item Layout Section Group Groups can be nested indefinitely.

Slide 33

Slide 33 text

Layout, Section, Group, Item Layout Section Group There's no limit for nesting.

Slide 34

Slide 34 text

Layout, Section, Group, Item Layout Section Group This brings tremendous flexibility!

Slide 35

Slide 35 text

Layout, Section, Group, Item Layout Section Group

Slide 36

Slide 36 text

Layout, Section, Group, Item Layout Section Group Item Group has items.

Slide 37

Slide 37 text

Layout, Section, Group, Item Layout Section Group Item Items are the smallest units that make up a layout, →

Slide 38

Slide 38 text

Layout, Section, Group, Item Layout Section Group Item and each item corresponds to a cell. →

Slide 39

Slide 39 text

Layout, Section, Group, Item Layout Section Group Item Eventually, the position of the item maps to the cell position.

Slide 40

Slide 40 text

Layout, Section, Group, Item Layout Section Group Item →

Slide 41

Slide 41 text

Layout, Section, Group, Item Layout Section Group Item Like that, the compositional layout can produce any complex layout to compose these four parts. It's like just configure than implement.

Slide 42

Slide 42 text

Section Let's try it out. Return to the example. A collection of components of the same kind can be represented as a section.

Slide 43

Slide 43 text

Group There is only one group occupies the whole width of the section. The height is fixed.

Slide 44

Slide 44 text

Group Item The group contains one item. The item occupies the whole width and height of the group.

Slide 45

Slide 45 text

let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(50)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) The code that achieves this layout looks like this: →

Slide 46

Slide 46 text

let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(50)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) The item I just explained is created programmatically.

Slide 47

Slide 47 text

let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(50)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) Also a group is created in the similar way. The group contains the item.

Slide 48

Slide 48 text

let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(50)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) Section has the group.

Slide 49

Slide 49 text

let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(50)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) When creating an item or group specify the size for them. We can use the relative value to specify the size from the container, which provides great flexibility.

Slide 50

Slide 50 text

let itemSize = ...Size(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) 100% 100% In this example, the width and height are specified as hundred % of the group. This means that this item will be of the same size as the group.

Slide 51

Slide 51 text

let itemSize = ...Size(widthDimension: .fractionalWidth(0.5), heightDimension: .fractionalHeight(1)) 50% 100% 50% 100% If the width is set to 0.5, the item will be half the width of the group and two items will be placed in the group.

Slide 52

Slide 52 text

let groupSize = ...Size(widthDimension: .fractionalWidth(1), heightDimension: .absolute(50)) 100% 50pt For the group, the width specified the same as the item fractionalWidth 1, so it is the same as the section width. On the other hand, the height is specified as absolute 50; then it will be 50 points height regardless of the size of the container.

Slide 53

Slide 53 text

let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(50)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) Basically this is all. You will find it very simple. You may think that using flow layout is easier or prefer nested collection views. Please wait. A compositional layout can produce any layout just by composing them. In other words, no matter how complex the layout you create, the code complexity will not increase any more. This means this is the upper limit for code complexity. So there are few bugs. Because it is just configuring not implement, we don't need to write any complex code.

Slide 54

Slide 54 text

Let's see for other section,

Slide 55

Slide 55 text

let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.92), heightDimension: .fractionalHeight(0.4)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) The code is very similar to the previous example. Only the size setting for the group are slightly different.

Slide 56

Slide 56 text

let groupSize = ...Size(widthDimension: .fractionalWidth(0.92), heightDimension: .fractionalHeight(0.4)) 92% 40% The height is 40% of the container. Specify the width 92%, so that you can see the next cell a little to indicate that it can scrolled horizontally.

Slide 57

Slide 57 text

How about another section? A group has multiple items.

Slide 58

Slide 58 text

let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.92), heightDimension: .fractionalHeight(0.3)) let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitem: item, count: 3) let section = NSCollectionLayoutSection(group: group) There are multiple ways to specify the size when a group contains multiple items.

Slide 59

Slide 59 text

let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitem: item, count: 3) Here, specify the number of items in the group so that the size is automatically determined equally. This method is useful when the number of items that the group contains is fixed. This is because the framework will automatically calculate the size that will fit exactly. We don't have to think about how much size to specify to fit into the group.

Slide 60

Slide 60 text

let layout = UICollectionViewCompositionalLayout { (sectionIndex, environment) -> NSCollectionLayoutSection? in switch sectionIndex { case 0: ... return section case 1: ... return section ... } } Compose Them into Layout All that remains is to composing them. Return each section object correspond to each section index.

Slide 61

Slide 61 text

when all the layouts for each section have seen have assembled, it looks like this.

Slide 62

Slide 62 text

Compositional layout determines the shape of the layout that is mapped to the cell, and the data flows in along the shape. Having such an image makes it easier to understand. →

Slide 63

Slide 63 text

Slide 64

Slide 64 text

Slide 65

Slide 65 text

Slide 66

Slide 66 text

Slide 67

Slide 67 text

Once this image is clear, you can easily code more complex layout, for another example, the layout above is used in Photos.app. →

Slide 68

Slide 68 text

Just place items in nested groups like this. If you create such a layout yourself by subclassing UICollectionViewlLayout or flow layout. You have to write complex code that interacts closely with the data to determine the size of each cell for each index.

Slide 69

Slide 69 text

As you have seen so far, the compositional layout represents any complicated layout with a composed of four parts. Therefore the code complexity does not increase. You can keep your code simple. We no longer need to implement UICollectionViewLayout. That's so cool! You think so too, right?

Slide 70

Slide 70 text

Oh, I forgot to mention a very powerful feature for modern apps. In the current state, all cells are arranged vertically. The identity of a cool modern app was a nested scroll, right?

Slide 71

Slide 71 text

... let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.92), heightDimension: .fractionalHeight(0.4)) let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [itemGroup]) let section = NSCollectionLayoutSection(group: group) section.orthogonalScrollingBehavior = .groupPagingCentered The compositional layout automatically generates nested scrolling by setting just one property.

Slide 72

Slide 72 text

Orthogonal Scrolling Behavior ... let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.92), heightDimension: .fractionalHeight(0.4)) let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [itemGroup]) let section = NSCollectionLayoutSection(group: group) section.orthogonalScrollingBehavior = .groupPagingCentered orthogonalScrollingBehavior. When this property is set, →

Slide 73

Slide 73 text

overflow items are automatically rendered →

Slide 74

Slide 74 text

on nested orthogonal scroll views.

Slide 75

Slide 75 text

orthogonalScrollingBehavior automatically extends the scroll axis in the orthogonal direction. →

Slide 76

Slide 76 text

No longer to place collection views on collection view, and write complex code to manage them. Simply handle simple collection view and data source. That's amazing!

Slide 77

Slide 77 text

So far, we have seen creating an AppStore app's UI using Compositional Layout. Is that true for Apple says the code become simple and surprisingly easy to create?

Slide 78

Slide 78 text

https://github.com/kishikawakatsumi/AppStore-Clone-CollectionViewCompositionalLayouts Yes! That's absolutely true. I actually tried it. Here is a clone of the AppStore sample app I made. This is just only a layout, but I was able to make it in 5, 6 hours. This project is published on GitHub, so you can see how the code simple and easy.

Slide 79

Slide 79 text

Only iOS 13? I'm sure you all think. It doesn't matter now because it can only be used on iOS 13. So it will be usable in two years. Two years later, we will be migrated SwiftUI.

Slide 80

Slide 80 text

https://github.com/kishikawakatsumi/IBPCollectionViewCompositionalLayout No, you can use it immediately. I created backport library to earlier iOS 12. It is called IBPCollectionViewCompositionalLayout.

Slide 81

Slide 81 text

IBPCollectionViewCompositionalLayout Please try IBPCollectionViewCompositionalLayout. The repository shows various complex layouts as sample code. You can see how easy to write any layout. And it works on iOS 12, 11, and 10.

Slide 82

Slide 82 text

Under development ✅ Spacing ✅ Nested Groups ✅ Supplemental Views (e.g. Section Header/Footers) ✅ Pinned Section Header/Footers ✅ Orthogonal Scrolling Behavior ✅ Estimated Size (Autosizing) ✅ Custom Group Item (Absolute Positions) ✅ Drop-in replacement ❌ RTL Support It is still under development, not fully supported functionality and lots of bugs left. But it's very helpful even now. AppStore clone app I mentioned works perfectly on earlier iOS 12.

Slide 83

Slide 83 text

For example, a layout has such complex headers and footers won't render correctly. But do we need to be able to create such a layout? I have no experience to make such a layout so far. Since I can create an App Store app layout, it can probably cover ninety-percent of use cases, I guess.

Slide 84

Slide 84 text

Drop-in Replacement - (instancetype)initWithSection:(IBPNSCollectionLayoutSection *)section { if (@available(iOS 13, *)) { return [[NSClassFromString(@"UICollectionViewCompositionalLayout") alloc] initWithSection:section]; } else { IBPUICollectionViewCompositionalLayoutConfiguration *configuration = [IBPUICollectionViewCompositionalLayoutConfiguration defaultConfiguration]; return [self initWithSection:section configuration:configuration]; } } The most interesting part of this library is that it provides a complete drop-in replacement. It provides emulated implementations on iOS 12 and below, but on iOS 13 and above, it automatically switches to the original implementation. In other words, there is nothing to do when you would omit support for iOS 12 in the future. No problem if you forget to remove this library because this library does nothing on iOS 13.

Slide 85

Slide 85 text

To develop this library, first I copied the interfaces from UIKit headers.

Slide 86

Slide 86 text

UICollectionViewLayout class UICollectionViewLayout { ... func prepare() func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> U func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICo func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool ... var collectionViewContentSize: CGSize { get } ... Then I gradually implemented a subclass of UICollectionViewLayout.

Slide 87

Slide 87 text

UICollectionViewLayout class UICollectionViewLayout { ... func prepare() func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> U func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICo func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool ... var collectionViewContentSize: CGSize { get } ... In shouldInvalidateLayout method, it returns a value whether invalidate previous layout and re-calculate the layout again.

Slide 88

Slide 88 text

UICollectionViewLayout class UICollectionViewLayout { ... func prepare() func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> U func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICo func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool ... var collectionViewContentSize: CGSize { get } ... In prepare method, calculate all positions of the cells.

Slide 89

Slide 89 text

UICollectionViewLayout class UICollectionViewLayout { ... func prepare() func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> U func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICo func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool ... var collectionViewContentSize: CGSize { get } ... layoutAttributesForItem method returns the position for cells on demand.

Slide 90

Slide 90 text

The first challenge was the nested groups. It was overcome by implementing the layout calculation method in a recursive structure.

Slide 91

Slide 91 text

Another challenge was orthogonal scrolling. As a result, it was surprisingly easy. It works just by creating a new collection view internally and passing a layout that changed the scroll direction. This implementation is smart without using black magic such as method swizzling, so please read the code if you are interested.

Slide 92

Slide 92 text

Wrap up • Collection View Compositional Layouts is incredible! • No need to implement collection view layout subclass • Like just editing configurations • Keep your code simple regardless layout become complex • You can use it now! (without iOS 13) Collection View Compositional Layouts is incredible! No need to implement collection view layout subclass Like just editing configurations Keep your code simple regardless layout become complex You can use it now! (without iOS 13)

Slide 93

Slide 93 text

Pitfalls It's such a great API, but there are some problems.

Slide 94

Slide 94 text

No Documentation There is still no documentation. We have to code with only on header comments, WWDC session videos and sample code. The sample code available from my repository is surely a great help.

Slide 95

Slide 95 text

2019-09-20 07:14:13.535020+0900 ... [29591:20271214] [CompositionalLayout] Attempting to add contentInsets to an item's dimension along an estimated axis. This layout axis insets will be ignored (however, any non-estimated axis insets will be applied). Please consider using the item's edgeSpacing or the containing group's interItemSpacing instead. The behavior of this API is not documented at all, but I found there are some settings that do not work well. When stepping on such a trap, you may see a warning at the console. You can see the setting that does not work.

Slide 96

Slide 96 text

References • IBPCollectionViewCompositionalLayout
 https://github.com/kishikawakatsumi/IBPCollectionViewCompositionalLayout • App Store.app Clone
 https://github.com/kishikawakatsumi/AppStore-Clone-CollectionViewCompositionalLayouts If you are interested in CompositionalLayout listening to this session, please try it. The my GitHub repositories have a lots of examples.

Slide 97

Slide 97 text

References • Advances in Collection View Layout
 https://developer.apple.com/videos/play/wwdc2019/215/ • All you need to know about UICollectionViewCompositionalLayout
 https://medium.com/flawless-app-stories/all-what-you-need-to-know-about- uicollectionviewcompositionallayout-f3b2f590bdbe • Using CollectionView Compositional Layouts in Swift 5
 https://dev.to/kevinmaarek/using-collectionview-compositional-layouts-in-swift-5-1nan • Move your cells left to right, up and down on iOS 13 — Part 1
 https://medium.com/shopback-engineering/move-your-cells-left-to-right-up-and-down-on- ios-13-part-1-1a5e010f48f9 You’d like to learn more about the concepts we’ve discussed here today, I strongly encourage you to check out the Advances in Collection View Layout session from this year’s WWDC. I hope this talk will help you develop your app in the future. It’s been an absolute pleasure speaking with you! Thank you for your time. I hope you enjoy the rest of your conference :)