TimesSquare: a calendar view for iOS and Android apps

January 31, 2013

Have you sent a gift card with Square Wallet yet? You can treat all of your friends to their favorite neighborhood spot -- no matter where you are -- instantly from your phone.

And if you're one to leave gift-giving to the last minute, Square has you covered. Your sweetheart will never be disappointed when you pre-select the day you want the gift card delivered.

To create this feature, we implemented a fully visual monthly calendar. Here are the details:

Open source options abound

We looked at a number of libraries for implementing this view in Square Wallet, including Kal, TapkuLibrary, GCCalendar, and ios-calendar on iOS, and android-calendar-view and the built-in CalendarView on Android. All of these are great libraries, but none of them gave us the level of flexibility we needed to implement a consistent Square look and feel on both platforms. So we ended up implementing one from scratch, and we called it TimesSquare.

Implementation details

For iOS, NSCalendar is ridiculously well-documented and flexible: it supports eleven different calendar systems, all kinds of arbitrary date calculations, and all of the historical offsets baked in to our common Gregorian calendar. Figuring out what to put in a calendar is relatively easy. We wrapped a UITableView and reused its standard paradigm of one cell per row to display the weeks of the calendar. We used another row for each month header, and the rest was relatively simple. A bit of clever rounding logic was necessary since 320 isn't divisible by 7, but we decided on a standard for that, as well.

For Android, we use the standard Java Calendar class to do our date calculations. We considered using a third-party date library but decided to keep our library's footprint as small as possible. As for the layout, we wrote a custom ListView: each row represents one month. Each MonthView uses custom measurement and layout logic for optimal scrolling speed.

Of course it's open source

We released the libraries on GitHub (iOS and Android) under our standard Apache license. The libraries are dead-simple to use.

iOS Usage

In your view controller's -loadView method, do something like this:

CGRect frame = self.parentViewController.view.bounds;
self.view = [[[TSQCalendarView alloc] initWithFrame:frame] autorelease];
self.calendarView.firstDate = [NSDate date];
self.calendarView.lastDate = [[NSDate date] dateByAddingTimeInterval:60 * 60 * 24 * 279.5]; // approximately 279.5 days in the future
self.calendarView.delegate = self;

If you've ever customized a UITableView, you'll find it easy to customize a TSQCalendarView. From simply subbing in different background images to deciding that, in fact, you want to make each column a different width, it's as simple as overriding a method in your cell subclass to do what you want.

Android Usage

Simply add the following xml to your layout:

<com.squareup.timessquare.CalendarPickerView
android:id="@+id/calendar_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

Include the library either by adding a Maven dependency or checking out the code and referring to it as a library project. Any of the styles can be overridden by your app if you want a different look and feel.

Contribute

We hope you enjoy using TimesSquare in your apps, and we hope you contribute back any improvements you make!

For more, take a look at the follow-up post about how we took TimesSquare's performance from stuttering so badly you'd get lost to scrolling like butter.

Jim Puls
iOS Engineer. Eternally curious. @puls.
Eric Denman
Android Engineer. @beerandpork.

Comments

Get support help at squareup.com/support. We'll delete off-topic comments.