Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swift India Conf 2019: Building Apps with Compositional Layout

Swift India Conf 2019: Building Apps with Compositional Layout

Speaker: Sowndharya Maheswaran, iOS Developer, Zoho

Twitter: https://twitter.com/_sowndharya/

Bio: An iOS developer working at Zoho. A huge fan of the data handling layer in a product. Loves writing frameworks. A math-aficionado who also spends a considerable amount of time on books on philosophy.

Abstract: Collection Views are the go-to components to build our layouts, however sophisticated they might appear to be. With iOS 13, Apple has provided with a hassle-free, (unpredicted) warning-free solution to arrange our views. In this talk, we’re going to explore all that you need to know about the new ‘Compositional Layout’ to implement interfaces ranging from simple lists to interactive windows.

Eeb061c8b2816b771920da1b3e7904a3?s=128

Swift India

July 28, 2019
Tweet

Transcript

  1. Building Apps with Compositional Layouts Sowndharya M iOS Engineer, Zoho

    Corporation
  2. Imagine building this…

  3. Nested Collection Views Distinct Layouts Estimated Sizing Paging

  4. class PagedCollectionViewLayout: UICollectionViewFlowLayout { static let CollectionViewWidth: CGFloat = screenWidth

    static let MinimumSpacingBetweenCells: CGFloat = 30 static let DistanceFromEdgeOfScreen: CGFloat = 55 override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { guard let collectionView = self.collectionView else { return proposedContentOffset } let pageWidth = itemSize.width + PagedCollectionViewLayout.MinimumSpacingBetweenCells let rawPageValue = collectionView.contentOffset.x / pageWidth let currentPage = velocity.x > 0 ? floor(rawPageValue) : ceil(rawPageValue) let nextPage = velocity.x > 0 ? ceil(rawPageValue) : floor(rawPageValue) let pannedLessThanPage = abs(1 + currentPage - rawPageValue) > 0.3 let flicked = abs(velocity.x) > 0.3 var offset = proposedContentOffset if pannedLessThanPage && flicked { offset.x = nextPage * pageWidth } else { offset.x = round(rawPageValue) * pageWidth } return offset } } extension ViewController: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TextCell.reuseIdentifier, for: indexPath) as? InnerCollectionCell else { return UICollectionViewCell() } cell.collectionView.delegate = self cell.collectionView.dataSource = self return cell } }
  5. Possible in 5 lines of code?

  6. What exactly is happening?

  7. F E D A B C Flow Layout

  8. Leads us to… Nested Scroll Views Self-sizing cells Boilerplate code

  9. ! Caution The behavior of the UICollectionViewFlowLayout is not defined

    because: The item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values.
  10. Compositional Layout

  11. Stitching small groups Composing > Sub Classing Compositional Layout

  12. //Abstraction Layers size = LayoutSize(width: .fractionalWidth(1.0), height: .absolute(44.0)) item =

    LayoutItem(layoutSize: size) group = LayoutGroup.horizontal(layoutSize: size, subitems: [item]) section = LayoutSection(group: group) layout = CompositionalLayout(section: section)
  13. Layout Section Groups Item

  14. Layout Size NSCollectionLayoutSize init(width: LayoutDimension, height: LayoutDimension) Re-defining dimensions

  15. Layout Dimension NSCollectionLayoutDimension fractionalWidth(_ fractionalWidth: CGFloat) fractionalHeight(_ fractionalHeight: CGFloat) absolute(_

    absoluteDimension: CGFloat) estimated(_ estimatedDimension: CGFloat) Axis Independent Four variants
  16. Layout Dimension let widthDimension = NSLayoutDimension.fractionalWidth(0.5) 0.5

  17. Layout Dimension let heightDimension = NSLayoutDimension.fractionalHeight(0.3) 0.3

  18. Layout Dimension let size = LayoutSize(widthDimension: .fractionalWidth(0.25), heightDimension: .fractionalWidth(0.25)) 0.25

    0.25
  19. Layout Item NSCollectionLayoutItem init(layoutSize: NSCollectionLayoutSize) var contentInsets: NSDirectionalEdgeInsets Basically a

    cell…
  20. Layout Group NSCollectionLayoutGroup: NSCollectionLayoutItem horizontal(layoutSize: LayoutSize, subitems: [LayoutItem]) vertical(layoutSize: LayoutSize,

    subitems: [LayoutItem]) custom(layoutSize: LayoutSize, ………) The workhouse Little mini flow layouts
  21. Layout Section NSCollectionLayoutSection init(layoutGroup: NSCollectionLayoutGroup) var contentInsets: NSDirectionalEdgeInsets Surprise property!!!

  22. The Layout UICollectionViewCompositionalLayout init(section: LayoutSection) init(sectionProvider: @escaping SectionProvider) Includes per

    section definition
  23. Let's Compose

  24. Simple Lists

  25. 1.0 size = LayoutSize(width: .fractionalWidth(1.0), height: .absolute(44.0)) item = LayoutItem(layoutSize:

    size) group = LayoutGroup.horizontal(layoutSize: size, subitems: [item]) 1.0
  26. Simple Lists

  27. Simpler Grids

  28. Simpler Grids

  29. Can we please address the
 AppStore problem now..?!

  30. Estimated Self-Sizing Per axis Dynamic text

  31. Distinct Sections

  32. layout = CompositionalLayout(section: section) //Or layout = CompositionalLayout { (sectionIndex:

    Int, layoutEnvironment: LayoutEnvironment) -> LayoutSection? in group = // Based on section section = LayoutSection(group: group) return section } return layout
  33. layout = CompositionalLayout(section: section) //Or layout = CompositionalLayout { (sectionIndex:

    Int, layoutEnvironment: LayoutEnvironment) -> LayoutSection? in group = // Based on section section = LayoutSection(group: group) return section } return layout
  34. layout = CompositionalLayout(section: section) //Or layout = CompositionalLayout { (sectionIndex:

    Int, layoutEnvironment: LayoutEnvironment) -> LayoutSection? in group = // Based on section section = LayoutSection(group: group) return section } return layout
  35. Nested Groups

  36. Unlimited Possibilities

  37. Where is the Nested Collections, Paging in these five lines?

  38. There is a 6th Line

  39. section.orthogonalScrollingBehavior = .continuous

  40. // Orthogonal Scrolling Sections enum Section Orthogonal Scrolling Behavior case

    none case continuous case continuousGroupLeadingBoundary case paging case groupPaging case groupPagingCentered
  41. Case study

  42. AppStore

  43. Layout

  44. Sections

  45. Horizontal Group Vertical Group

  46. Horizontal Group Vertical Group Item Width - 1.0 Item Count

    - 3
  47. Pinterest

  48. Layout

  49. Horizontal
 Group Group Width - 0.5

  50. Vertical
 Groups Item Height - Absolute

  51. Credits https://developer.apple.com/videos/play/wwdc2019/215 https://github.com/jVirus/compositional-layouts-kit https://gist.github.com/breeno/f16330c5ef06075b0fc476c65d9b00d8