Skip to content

An experiment with building a calendar using UICollectionViewCompositionalLayout

Notifications You must be signed in to change notification settings

wmcginty/CompositionalCalendar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Overview

This project is an ongoing experiment to recreate the interactions of the stock iOS Calendar app, using UICollectionViewCompositionalLayout. While I have tried not to cut corners and hardcode things, using Calendar APIs wherever possible, I would not recommend using this in production code without taking a long hard look at it first.

The basic calendar is constructed using a hierarchy of 4 types:

  • Timeline
  • Year
  • Month
  • Day

The Timeline acts as the data source of the calendar and holds a mutable [Year]. Starting at a given date, the Timeline will populate a period of time around that date to facilitate initial scrolling.

Each of these Years has (predictably) an [Month], calculated by iterating over Calendar.range(of:in:for). These months, in turn, store the firstDate in that month, the weekday offset (using Calendar.component(_:from:)) and a [Day]. Each Day contains the Date it represents, the index in the month as well as a Bool that represents whether or not it is in the weekend.

Infinite Scrolling

Infinite scrolling in action. Note: the frame rate is smoother and the image is sharper on an actual simulator / device

In order to infinitely scroll in either direction around a given date - the contents of the data source has to change. You can't just store a ridiculously large amount of dates in an array and hope for the best.

As the user scrolls, the collection view is monitoring that content offset. If the user reaches either the top or bottom of the content size, it triggers a data source update. If the user hits the top of the collection view, a new year is prepended to the data source, and any excess years in the other direction are removed. If the user reaches the bottom of the collection view, a new year is appended to the data source and any excess years earlier are removed to keep the data size small.

This modification logic is performed just before the collection view lays out it's subviews to ensure that visual glitches in the collection view do not occur. In addition, contentOffset is modified directly instead of using setContentOffset(_:animated:) to maintain existing scrolling velocity.

About

An experiment with building a calendar using UICollectionViewCompositionalLayout

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages