New to Telerik UI for Xamarin? Download free 30-day trial

TKCalendar for Xamarin.iOS: Getting Started

This quick start tutorial demonstrates how to create a simple iOS application with TKCalendar.

Setting up TKCalendar

Since iOS 10, Apple requires explicit description when NSCalendar is being used, more precisely when one is trying to access the phone's calendar events. This description is prompted to the user, only when there is an attempt for accessing events, and requires user's confirmation.

If you are using Telerik UI for Xamarin.iOS but never accessing device's calendar your users won't get prompted with this message.

In order to submit your application to the AppStore make sure to include a NSCalendarsUsageDescription variable to your info.plist and provide some description, for example "This application need to acces your calendar events."

Now that our project is created and the TelerikUI.framework is added, we can start referencing and using the TelerikUI types:

Open your UIViewController file and add a reference to Telerik UI header file:

using TelerikUI;

Note that starting with Xcode 6 Apple doesn't generate the precompiled headers file automatically. That is why you should add import the UIKit framework before importing TelerikUI:

using UIKit;

Type the following code in ViewDidLoad method:

TKCalendar calendarView = new TKCalendar (this.View.Bounds);
calendarView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
this.View.AddSubview (calendarView);

This code creates a new instance of TKCalendar and adds it as a subview of the ViewController's main view. The AutoresizingMask property is set in order to allow correct resizing of the calendar when the device is rotated in landscape mode.

Events

The next step is to create some random data that will be consumed by the calendar. You can use the following code:

events = new List<TKCalendarEvent> ();
NSCalendar calendar = new NSCalendar (NSCalendarType.Gregorian);
NSDate date = NSDate.Now;

Random r = new Random ();
for (int i = 0; i < 3; i++) {
    TKCalendarEvent ev = new TKCalendarEvent ();
    ev.Title = "Sample event";
    NSDateComponents components = calendar.Components (NSCalendarUnit.Day | NSCalendarUnit.Month | NSCalendarUnit.Year, date);
    components.Day = r.Next () % 20;
    ev.StartDate = calendar.DateFromComponents (components);
    ev.EndDate = calendar.DateFromComponents (components);
    ev.EventColor = UIColor.Red;
    events.Add (ev);
}

This code will add 10 events with random dates to an array named events. The arc4random method is being used to create the random dates. The code also assigns a title and a color to the events.

Now let's add this random data to the calendar and present it. In order to do this, we should first adopt the TKCalendarDataSource protocol:

class CalendarDataSource : TKCalendarDataSource

And we should implement its EventsForDate: method:

public TKCalendarEventProtocol[] EventsForDate (TKCalendar calendar, NSDate date)
{
    NSDateComponents components = calendar.Calendar.Components (NSCalendarUnit.Day | NSCalendarUnit.Month | NSCalendarUnit.Year, date);
    components.Hour = 23;
    components.Minute = 59;
    components.Second = 59;
    NSDate endDate = calendar.Calendar.DateFromComponents (components);
    List<TKCalendarEventProtocol> filteredEvents = new List<TKCalendarEventProtocol> ();
        for (int i = 0; i < this.events.Count; i++) {
            TKCalendarEventProtocol ev = this.events[i];
            if (ev.StartDate.SecondsSinceReferenceDate <= endDate.SecondsSinceReferenceDate && 
                ev.EndDate.SecondsSinceReferenceDate >= date.SecondsSinceReferenceDate) {
                filteredEvents.Add (ev);
            }
    }
    return filteredEvents.ToArray ();
}

Here, the predicate is used to filter the events array by date. Do not forget to assign the DataSource property of TKCalendar:

calendarView.DataSource = new CalendarDataSource (this);

For information about populating TKCalendar with EventKit events, please refer to the following article: Populating with data

Calendar MinDate and MaxDate

As a next step you may want to tune up the calendar more precisely by specifying minimum and maximum allowed dates. This can be done by setting the MinDate and MaxDate properties:

calendarView.MinDate = TKCalendar.DateWithYear (2010, 1, 1, calendar);
calendarView.MaxDate = TKCalendar.DateWithYear (2016, 12, 31, calendar);

By default, TKCalendar displays the current date, use the NavigateToDate method to display a different date:

NSDateComponents newComponents = new NSDateComponents();
newComponents.Year = 2015;
newComponents.Month = 5;
newComponents.Day = 1;
NSDate newDate = calendarView.Calendar.DateFromComponents (newComponents);
calendarView.NavigateToDate (newDate, true);

Notification when date is selected

TKCalendar sends different notifications. For example, in order to be notified when a date was selected, override the DidSelectDate method of TKCalendarDelegate protocol:

class CalendarDelegate : TKCalendarDelegate
{
    public override void DidSelectDate (TKCalendar calendar, NSDate date)
    {
        Console.WriteLine ("{0}", date);
    }
}

Selection Modes

Note that TKCalendar supports single, multiple and range date selection. Selection modes are described in detail in the article about Selection.

Along with selection notifications TKCalendar supports navigation and customization notifications by adopting the TKCalendarDelegate protocol. These notifications are described in the articles about: Navigation and Customizations.

Here is the full code of this example:

    public class CalendarDocsWithSimpleEvent : XamarinExampleViewController
    {
        CalendarDelegate calendarDelegate;
        List<TKCalendarEvent> events;

        public TKCalendar CalendarView {
            get;
            set;
        }

        public TKCalendarEventProtocol[] EventsForDate {
            get;
            set;
        }

        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();
            TKCalendar calendarView = new TKCalendar (this.View.Bounds);
            calendarView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
            this.View.AddSubview (calendarView);

            calendarDelegate = new CalendarDelegate ();

            calendarView.DataSource = new CalendarDataSource (this);

            events = new List<TKCalendarEvent> ();
            NSCalendar calendar = new NSCalendar (NSCalendarType.Gregorian);
            NSDate date = NSDate.Now;

            Random r = new Random ();
            for (int i = 0; i < 3; i++) {
                TKCalendarEvent ev = new TKCalendarEvent ();
                ev.Title = "Sample event";
                NSDateComponents components = calendar.Components (NSCalendarUnit.Day | NSCalendarUnit.Month | NSCalendarUnit.Year, date);
                components.Day = r.Next () % 20;
                ev.StartDate = calendar.DateFromComponents (components);
                ev.EndDate = calendar.DateFromComponents (components);
                ev.EventColor = UIColor.Red;
                events.Add (ev);
            }

            calendarView.MinDate = TKCalendar.DateWithYear (2010, 1, 1, calendar);
            calendarView.MaxDate = TKCalendar.DateWithYear (2016, 12, 31, calendar);

//            calendarDelegate.events = this.events;
            calendarView.Delegate = calendarDelegate;

            NSDateComponents newComponents = new NSDateComponents();
            newComponents.Year = 2015;
            newComponents.Month = 5;
            newComponents.Day = 1;
            NSDate newDate = calendarView.Calendar.DateFromComponents (newComponents);
            calendarView.NavigateToDate (newDate, true);

            calendarView.ReloadData();
        }

        class CalendarDataSource : TKCalendarDataSource
        {
            CalendarDocsWithSimpleEvent main;
            public List<TKCalendarEvent> events;
            public CalendarDataSource(CalendarDocsWithSimpleEvent main)
            {
                this.main = main;
            }

            public TKCalendarEventProtocol[] EventsForDate (TKCalendar calendar, NSDate date)
            {
                NSDateComponents components = calendar.Calendar.Components (NSCalendarUnit.Day | NSCalendarUnit.Month | NSCalendarUnit.Year, date);
                components.Hour = 23;
                components.Minute = 59;
                components.Second = 59;
                NSDate endDate = calendar.Calendar.DateFromComponents (components);
                List<TKCalendarEventProtocol> filteredEvents = new List<TKCalendarEventProtocol> ();
                    for (int i = 0; i < this.events.Count; i++) {
                        TKCalendarEventProtocol ev = this.events[i];
                        if (ev.StartDate.SecondsSinceReferenceDate <= endDate.SecondsSinceReferenceDate && 
                            ev.EndDate.SecondsSinceReferenceDate >= date.SecondsSinceReferenceDate) {
                            filteredEvents.Add (ev);
                        }
                }
                return filteredEvents.ToArray ();
            }
        }

        class CalendarDelegate : TKCalendarDelegate
        {
            public override void DidSelectDate (TKCalendar calendar, NSDate date)
            {
                Console.WriteLine ("{0}", date);
            }
        }


}

Change Calendar View Mode

You can easily change the way data is presented in chart by changing the view mode property:

this.CalendarView.ViewMode = TKCalendarViewMode.Year;

All view modes are described in the following article: View modes

In this article