While SwiftUI is an extremely useful framework to create complex views, we all know that UIKit is here to stay for a good amount of time. Apple has made the Collection Views even more powerful this year with the release of new APIs. Compositional Layout lets you create complex and intricate collection views in SwiftUI really easily. We will create a simple collection view layout that has horizontal scrolling, and each row contains three cells. One on the left side and two stacked together on the right. Let's start by writing the CollectionViewCell and UICollectionView code. The cell will be really simple: UIKit { containerView: = { view = () view.backgroundColor = .white view.translatesAutoresizingMaskIntoConstraints = view }() (frame: ) { . (frame: frame) configureViews() } { addSubview(containerView) containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = containerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = containerView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = containerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = } ?(coder: ) { ( ) } } import : class QuickCell UICollectionViewCell let UIView let UIView false return override init CGRect super init func configureViews () true true true true required init NSCoder fatalError "init(coder:) has not been implemented" In our , we will set up the collection view: ViewController { collectionView: ! dataColors = [ [ .red, .blue, .green, .magenta, .purple, .orange, .black, .lightGray, .blue], [ .red, .blue, .green, .magenta, .blue] ] { .viewDidLoad() collectionView = (frame: .zero, collectionViewLayout: createCustomLayout()) collectionView.backgroundColor = .white .collectionView.delegate = .collectionView.dataSource = .collectionView.register( . , forCellWithReuseIdentifier: ) configureCollectionView() } { collectionView.translatesAutoresizingMaskIntoConstraints = .view.addSubview(collectionView) .activate([ .collectionView.topAnchor.constraint(equalTo: .view.layoutMarginsGuide.topAnchor), .collectionView.bottomAnchor.constraint(equalTo: .view.bottomAnchor), .collectionView.leftAnchor.constraint(equalTo: .view.leftAnchor), .collectionView.rightAnchor.constraint(equalTo: .view.rightAnchor) ]) } -> { dataColors. } -> { dataColors[section]. } -> { cell = collectionView.dequeueReusableCell(withReuseIdentifier: , : indexPath) ? { colorArray = dataColors[indexPath.section] cell.containerView.backgroundColor = colorArray[indexPath.row] cell } { () } } : , , class ViewController UIViewController UICollectionViewDelegate UICollectionViewDataSource var UICollectionView let UIColor UIColor UIColor UIColor UIColor UIColor UIColor UIColor UIColor UIColor UIColor UIColor UIColor UIColor override func viewDidLoad () super // Do any additional setup after loading the view. UICollectionView self self self self self QuickCell self "cellID" func configureCollectionView () false self NSLayoutConstraint self self self self self self self self func numberOfSections ( collectionView: UICollectionView) in Int return count func collectionView ( collectionView: UICollectionView, numberOfItemsInSection section: Int) _ Int return count func collectionView ( collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) _ UICollectionViewCell if let "cellID" for as QuickCell let return else return UICollectionViewCell The above code is quite simple. I have created an array which has two arrays in it. Then I have created a collectionView and initiated it with a function (more on this in a bit). Then I have just added the collectionView as a subView and configured auto-layout constraints. createCustomLayout() Now let's get to the fun stuff! The main thing to understand here is what is , and . We design a section by creating a group. That group then contains items. Item Group Section In the above picture, you can see the section dissected. In the section, we have two groups. (two black boxes). In each group, we have item. The left group contains one item, while the right group contains two items. This is also where we have nested groups in action. We are adding two groups inside one group to create a section. Let's see how we can achieve this using code. -> { layout = { (section: , environment: ) -> ? leadingItem = (layoutSize: (widthDimension: .fractionalWidth( ), heightDimension: .fractionalHeight( ))) leadingItem.contentInsets = (top: , leading: , bottom: , trailing: ) leadingGroupSize = (widthDimension: .fractionalWidth( ), heightDimension: .fractionalHeight( )) leadingGroup = .vertical(layoutSize: leadingGroupSize, subitem: leadingItem, : ) trailingItem = (layoutSize: (widthDimension: .fractionalWidth( ), heightDimension: .fractionalHeight( ))) trailingItem.contentInsets = (top: , leading: , bottom: , trailing: ) trailingGroupSize = (widthDimension: .fractionalWidth( ), heightDimension: .fractionalHeight( )) trailingGroup = .vertical(layoutSize: trailingGroupSize, subitem: trailingItem, : ) containerGroupSize = (widthDimension: .fractionalWidth( ), heightDimension: .absolute( )) containerGroup = .horizontal(layoutSize: containerGroupSize, subitems: [leadingGroup, trailingGroup]) section = (group: containerGroup) section.orthogonalScrollingBehavior = .continuousGroupLeadingBoundary section.contentInsets = (top: , leading: , bottom: , trailing: ) section } layout } } func createCustomLayout () UICollectionViewLayout let UICollectionViewCompositionalLayout Int NSCollectionLayoutEnvironment NSCollectionLayoutSection in let NSCollectionLayoutItem NSCollectionLayoutSize NSCollectionLayoutDimension 1.0 1.0 NSDirectionalEdgeInsets 5 5 5 5 let NSCollectionLayoutSize 0.7 1 let NSCollectionLayoutGroup count 1 let NSCollectionLayoutItem NSCollectionLayoutSize NSCollectionLayoutDimension 1.0 1.0 NSDirectionalEdgeInsets 5 5 5 5 let NSCollectionLayoutSize 0.3 1 let NSCollectionLayoutGroup count 2 let NSCollectionLayoutSize 1.0 250 let NSCollectionLayoutGroup let NSCollectionLayoutSection NSDirectionalEdgeInsets 20 0 20 0 return return We will be using UICollectionViewCompositionalLayout initializer that comes with a closure. The code inside the closure will return NSCollectionLayoutSection. This section will then create the UICollectionViewLayout which we will return outside the closure. We won't be using section and environment parameters in this tutorial, however we can use the environment parameter if the user rotates the device and now we want to change the number of columns shown when the device is in landscape orientation and so forth. Section parameter can be used if you want different number of columns or items in each section. Now we will start by creating the items. The leading item (left item) will be initialized like so: leadingItem = (layoutSize: (widthDimension: .fractionalWidth( ), heightDimension: .fractionalHeight( ))) let NSCollectionLayoutItem NSCollectionLayoutSize NSCollectionLayoutDimension 1.0 1.0 and represent how wide and high should the item be as compared to its parent container. For items, their parent container is group. Then we will create the . For that we need to create the group size. fractionalWidth fractionalHeight leadingGroup leadingGroupSize = (widthDimension: .fractionalWidth( ), heightDimension: .fractionalHeight( )) leadingGroup = .vertical(layoutSize: leadingGroupSize, subitem: leadingItem, : ) let NSCollectionLayoutSize 0.7 1 let NSCollectionLayoutGroup count 1 The group will be 70% of the parent container, which in this case will be the containerGroup. The height will be the height of the section. (we will set this in just a moment). Then we will create the group, and the group can have items stacked either horizontally or vertically. We give the initializer the group size, the item which will go in and the count. Count basically means how many items should go in this group. Setting this overrides item's dimensions (width or height depending upon horizontal or vertical axis). Since the count is 1, it will cover the entire dimensions of the group. Now let's create the trailing group and item. trailingItem = (layoutSize: (widthDimension: .fractionalWidth( ), heightDimension: .fractionalHeight( ))) trailingItem.contentInsets = (top: , leading: , bottom: , trailing: ) trailingGroupSize = (widthDimension: .fractionalWidth( ), heightDimension: .fractionalHeight( )) trailingGroup = .vertical(layoutSize: trailingGroupSize, subitem: trailingItem, : ) let NSCollectionLayoutItem NSCollectionLayoutSize NSCollectionLayoutDimension 1.0 1.0 NSDirectionalEdgeInsets 5 5 5 5 let NSCollectionLayoutSize 0.3 1 let NSCollectionLayoutGroup count 2 Similar to the , this item also takes 100% dimensions of the parent container. However, the group size is 30% of the width and height is 100% of the section height. The trailingGroup however is initialized by giving the count parameter a value of 2. This overrides the item's height dimensions and divides the height by 2. leadingItem So now the leading group contains one item and the trailing group contains two items. We can have different number of items stacked vertically in either group just by changing the count parameter. Now let's create the , that will hold the entire sub groups. This is called . You can have unlimited nested groups inside your layout. So essentially we have a group, that contains two different groups, each group then contains items. containerGroup nested-groups This is the : containerGroup containerGroupSize = (widthDimension: .fractionalWidth( ), heightDimension: .absolute( )) containerGroup = .horizontal(layoutSize: containerGroupSize, subitems: [leadingGroup, trailingGroup]) let NSCollectionLayoutSize 1.0 250 let NSCollectionLayoutGroup The has absolute height of 250 and the width of the collectionView. Then we are using the horizontal axis for the layout group and giving it the group size and an array of subitems, which are and . containerGroup leadingGroup trailingGroup Finally we create the section, and provide the section an orthogonalScrollingBehavior to get horizontal scrolling within each section. We get six different behaviors to choose from - I have selected , which always align the group's leading boundary whenever you scroll. continuousGroupLeadingBoundary Here is the app in action: Awesome, right? Compositional Layout is an extremely powerful Swift API, that allows us to avoid a ton of boilerplate code and write a complex collection view layout concisely and efficiently. To see this example in practice, check out this . Swift app template As you can see, with less than 15 lines of code, we were able to mimic the layout above. Historically, this has been an arduous task, but fortunately Apple came up with a better API at the latest WWDC. This finally brought this task to the same level of simplicity as the collections. React Native Give this code a try, and let us know what you build with it. You can read more about in the Apple's official docs. Compositional Layout