Solstice



UI/UX | UX Research | Workshops | Branding | Overall Design Works

Solstice is a project that started with a simple idea: what if I could see how much more or less daylight there is today compared to yesterday? But simple ideas can be complex to build. I wanted to share this deep dive into the work that went into making Solstice a powerful tool that’s still simple to use.



Duration
Q2,3 2023, 1.5 months

Team
Michelle Cedeño
Seojin, 
Hanmo, 
Taehwa

My Role
Research & Strategy Lead
UI/UX Design
Persona Building

Methods
Figma, 
Midjourney, 
Maze, 
After Effects 


.




The Challenge





Solstice is a project close to my heart. When I was working in my first job in London, England, I spent most of my day in an office that had no external windows. During the winter, this meant I didn’t see sunlight during the work week—I’d go into the office before the sun rose, and I wouldn’t leave until after it had set.

This experience underscored the effect that sunlight has on my mood and mental well-being. When, during the winter of 2020/2021, COVID-19 made an already-dreary season even drearier, I decided to build an app that would help me quantify the change in daylight, and give me something to look forward to.

The app is built in SwiftUI and works on iPhone, iPad, macOS, and Apple Watch. It’s privacy-sensitive by default, asking only for the permissions it needs (approximate location) and works without access to your location unless you explicitly grant permissions.



Solstice works across iPhone, iPad, macOS, and Apple Watch, and features widgets, daily notifications, and Shortcuts support.


Time Travel


One of Solstice’s core features is Time Travel; the ability to compare today’s daylight to any other date. In the first version of Solstice, a slider was used to allow quick time travel to dates in the past or future. This affordance is easy to use, but imprecise: on smaller iPhone screens, individual days might end up less than 1px apart on the slider, making it impossible to choose a specific date. 

This meant the “Time Machine” for controlling time travel needed three properties:
  1. A reference date (the date we want to travel from—usually the current date)
  2. A target date (the date we want to travel to)
  3. An offset representing the number of days between the reference and target dates

To keep the offset in sync with the reference and target dates, it needs to be its own computed value, and since we want to control it via a slider, it needs to be a Binding over a Double. Putting all this together, a simplified version of Solstice’s Time Machine looks like this:



The referenceDate is updated every minute in the app’s main view using a timer (I had explored using SwiftUI’s TimelineView for this update but found it degraded the app’s performance) and/or when the app (re)enters the foreground. The whole class is also run on the main thread thanks to the @MainActor attribute; this ensures the UI remains responsive when the Time Machine changes, which is important: almost everything on the screen is dependent on the Time Machine’s dates.

There’s one problem though; the hour, minute, and second components of the reference and target dates can drift. If you open the app at 9am and set the target date to some future date, when you reopen the app at 9pm, the app will still show you data matching 9am on the target date. To prevent this, we need 
one last computed property to synchronise the time components of the reference and 





target dates: