Building a Calendar Explorer App with SwiftUI

Building a Calendar Explorer App with SwiftUI

Calendar Explorer - an app for viewing different time periods - such as days, weeks, quarters, and times of day - and navigating between them using intuitive swipe gestures and a time scale picker.

In other words, it imitates the functionality of a typical calendar app.

This post details the process of building it, step by step. The result is available on GitHub here.

Step 0: Setting Up the Project

The project begins with an iOS App template in Xcode.

Here are the project options: the product name, which will also be the app name, is calendar-explorer; the interface is SwiftUI; and the organisation identifier, which can be any string, is set as the name of this blog.

The first commit shows progress up to this point.

Step 1: Time Modelling

At the core of the app is the manipulation of dates and times. A useful overview of Swift's capabilities in this area is this guide on date and time programming in Swift.

The second commit introduces the DateInfo struct and displays today's details:

The DateInfo struct acts as a wrapper for the Date struct, with its methods and properties providing custom data to the views. It represents the primary state of the app - a current position in time.

Step 2: Navigation Between Days

The third commit implements navigation between days via swiping. The present day is displayed in the centre, with the future to the right and the past to the left.

"To swipe left" means to place a finger on the right side of the screen and move it to the left side, pushing the current view towards left to access content to the right. In this case, swiping left moves from today to tomorrow, and swiping right moves from today to yesterday.

Swift locates each point on a screen using a rectangular coordinate system, centred in the top-left corner. The width dimension increases from left to right, and the height dimension from top to bottom. Therefore, a left swipe has a negative change in width (i.e. value.translation.width < 0), while a right swipe has a positive change.

Currently, the swipe-responsive area is limited to the rectangle with text at the centre of the screen. The fourth commit expands this area to the entire screen by claiming available space with Spacer()s and using the .contentShape(Rectangle()) modifier.

Step 3: A View for Every Time Scale

With basic functionality in place, the next step is to add more views to display different time scales: times of day, days, weeks, and quarters.

The fifth commit extracts the day view and sets up the TimeScale enum, which helps track the current time scale.

The sixth commit adds times of day:

The seventh commit adds weeks:

The eighth commit adds the simplest view of all - quarters:

The implementation follows a consistent pattern: adding a new view, new date info methods, extending the enum, and updating any switch statements to incorporate the new functionality.

Step 4: Three More Ways to Navigate

The ninth commit introduces vertical swipes to navigate up and down the time scales. Choosing which swipe direction moves to a longer or shorter time scale is arbitrary, and in this case, the upward direction leads to a longer time scale. This effect is achieved with a downward swipe on the screen, which corresponds to a positive change in height.

At this stage, all essential navigation is implemented. The next two navigation methods provide added convenience.

The tenth commit introduces a home button that resets the time to today and the time scale to .day.

The eleventh commit introduces a menu picker to directly select any time scale:

Conclusion

Calendar Explorer is an early-stage prototype that showcases a concept of swipe-based time navigation and multi-scale time views. It may grow into a proper app in the future.

Read more