An open source calendar framework for iOS, with support for customization, IBDesignable, Autolayout, and more.

Overview

Promo

About

MBCalendarKit is a calendar control written in Objective-C with modern best practices and Swift interoperability in mind.

It offers a flexible calendar control, with support for displaying any calendar system supported by NSCalendar. It also includes an API to customize the calendar cells. It also ships with a prebuilt view controller, inspired by the original iOS calendar.

Carthage compatible Build Status

Features

  • Interactive Calendar Control
  • Autolayout Support
  • Dynamic Framework for iOS 8+
  • Custom Cell API with Default Implementation
  • Calendar Event Display
  • Custom First Weekday
  • Clamp Dates to Minimum and/or Maximum Values
  • Display for Any Locale or Calendar Identifier
  • Display Modes: Month, Week, and Day
  • Localization Support, Including Right-to-Left and Date Formatting
  • Pre-built View Controller inspired by the original iOS Calendar App
  • Sample App With Various Demo Implementations

Getting Started:

You'll need to target iOS 8+. There are three four ways to integrate MBCalendarKit:

  1. Cocoapods: pod 'MBCalendarKit', '~> 5.0.0'
  2. Carthage: github MosheBerman/MBCalendarKit ~> 5.2.0
  3. Drag this Xcode project in to your own, and add the framework as a dependency.
  4. If you really want to drag the raw source in, the framework code is in MBCalendarKit/CalendarKit.

If there are any problems, please head over to issue #48 and leave a comment.

Swift & Objective-C

MBCalendarKit is written in Objective-C. To use MBCalendarKit with Swift, just link against and use import MBCalendarKit. MBCalendarKit 5.0.0 includes a number of Swift enhancements.

The examples here are in Swift, for berevity. Note that when writing Objective-C, MBCalendarKit prefixes its classes and enums with CK. CalendarView in Swift is CKCalendarView in Objective-C, etc.

For specifics, check out the Migration Guide.

Features

Presenting a Calendar

You have two choices for showing a calendar using MBCalendarKit.

  1. You can show an instance of CKCalendarView. Use this if you want to manually manage your view hierarchy or just want a calendar view without the events table view.
/// Here's how you'd show a CalendarView from within a view controller.
/// Import the framework, then it's just three easy steps.

import MBCalendarKit
    	
// 1. Instantiate a CKCalendarView
let calendar = CalendarView()
 		
// 2. Present the calendar 
self.view.addSubview(calendar)

// 3. Add positioning constraints:
self.calendarView.translatesAutoresizingMaskIntoConstraints = false
calendarView.topAnchor.constraint(equalTo:self.topLayoutGuide.bottomAnchor).isActive = true
calendarView.centerXAnchor.constraint(equalTo:self.view.centerXAnchor).isActive = true
  1. Your second option is to create an instance of CalendarViewController. Using a CKCalendarViewController gives you the added benefit of a "today" button and a segmented control in the toolbar, which allows you to select the display mode. In MBCalendarKit 5.0.0 and later, you also use CalendarViewController if you'd like an events table view.
/// Here's how you'd show a CalendarViewController from 
/// within a view controller. It's just three easy steps, including the framework import.
		
// 1. Import MBCalendarKit:
import MBCalendarKit
    	
// 2. Instantiate a CalendarViewController
let calendar = CalendarViewController()
 		
// 3. Present the calendar 
self.present(calendar animated:true completion:nil)
		

With both CalenderView and CalendarViewController, you can use the dataSource and delegate properties to display events, and get information about user interation.


Note: In older versions of MBCalendarKit, CKCalendarViewController used to subclass UINavigationViewController, so it couldn't be installed inside of another navigation controller. In 5.0.0, this is no longer the case. If you wish to embed your calendar inside a UINavigationViewController, you must now install it on your own. See the Migration Guide for details.


In MBCalendarKit 5.0.0, there's a new property on CalendarView called customCellProvider, which can be used to customize the display of the cells in a really powerful way. Keep reading to learn more about setting up events

Showing Events

The CKCalendarDataSource protocol defines a method, which supplies an array of CKCalendarEvent objects. The calendar view automatically shows an indicator in cells that represent dates that have events.

func calendarView(_ calendarView: CalendarView, eventsFor date: Date) -> [CalendarEvent]

In your data source, implement this method and return the events matching the date being passed in.

Here's an example of adding a few events to the calendar:

func adEventsToCalendar() {
  let title : NSString = NSLocalizedString("Add Swift Demo", comment: "") as NSString
    if let date : Date = NSDate(day: 9, month: 1, year: 2015) as Date?
    {
      let event : CalendarEvent = CalendarEvent(title: title as String, andDate: date, andInfo: nil)
      self.data[date] = [event]
    } 

    let title2 : NSString = NSLocalizedString("Release MBCalendarKit 5.0.0", comment: "") as NSString
    if let date2 : Date = NSDate(day: 15, month: 8, year: 2017) as Date?
    {
      let event2 : CalendarEvent = CalendarEvent(title: title2 as String, andDate: date2, andInfo: nil)
      self.data[date2] = [event2]
    }
}

Now, implement the data source:

//  MARK: - CalendarDataSource

override func calendarView(_ calendarView: CalendarView, eventsFor date: Date) -> [CalendarEvent] 
{
    let eventsForDate = self.data[date] ?? []
 
    return eventsForDate
}

Note: The dates used as keys must match the dates passed into the data source method exactly. One way to ensure this is to use the NSCalendar's isDate:equalToDate:toUnitGranularity:, passing in the two dates and .day as the third argument, to create the dates you pass to your events.

You can also see this code in CKDemoViewController.m or SwiftDemoViewController.swift in the demo app.

Handling User Interaction

These methods, defined in the CalendarViewDelegate protocol, are called on the delegate when the used selects a date. A date is considered selected when either an arrow in the header is tapped, or when the user lifts their finger from a cell.

func calendarView(_ calendarView: CalendarView, willSelect date: Date) 
func calendarView(_ calendarView: CalendarView, didSelect date: Date) 

This method is called on the delegate when a row is selected in the events table. You can use to push a detail view, for example.

func calendarView(_ calendarView: CalendarView, didSelect event: CalendarEvent) 

Customizing Cells

MBCalendarKit 5.0.0 brings a brand new way to customize cells, so that you can add your own data to the cells, or even do a completely design. By building on top of UICollectionView, MBCalendarKit provides a really simple API. First, you need to implement CustomCellProviding in your code. This is composed of two parts: First, telling MBCalendarKit which UICollectionViewCell subclass to use for the cells, and second, implementing a method callback which will be your opportunity to customize the cell based on its context.

Let's look at an implementation based on the default implementation:

// Step 1. Formally adopt the `CustomCellProviding` protocol
Class MyCustomCellProvider: NSObject, CustomCellProviding {

    // Step 2. Inform the framework of your `UICollectionViewCell` subclass, so it knows to use it.
    var customCellClass: AnyClass
    {
        return CKCalendarCell.self
    }

    // Step 3. Implement the custom cell delegate callback
    func calendarView(_ calendarView: CalendarView, willDisplay cell: UICollectionViewCell, in context: CalendarCellContext) {

        // It's reasonable to cast to whatever class is in `customCellClass`.
        guard let cell = cell as? CustomCalendarCell else
        {
            return
        }

        // Customize the cell's contents and display here.
    }
}

Now, simply tell the calendar view that your object is providing custom cells:

// 0. Assume an existing calendarView

// 1. Instantiate your custom cell provider.
let myCustomCellProvider = MyCustomCellProviderClass()

// 2. Assign the custom cell provider to the calendar view's customCellProvider.
calendarView.customCellProvider = myCustomCellProvider

That's it. The demo app and the migration guide have more information.


Note: Prior to MBCalendarKit, customization of the cell's appearance was limited to properties accessible via UIAppearance. Those UIAppearance methods are still available in MBCalendarKit 5.0.0.


Calendar Cell Contexts:

If you want to know which date the cell represents, or what scope the cell is being displayed in, look at the context object. CKCalendarCellContext has a few interesting properties:

To see the date represented by the cell, use the date property.:

var date: Date

To see if the cell represents today, is out of the month, or even out of range of the calendar's minimum and maximum dates, use the context's identifier property, which is one of several CalendarCellContextIdentifier values.

var identifier: CKCalendarCellContextIdentifier

The context identifier is based on several other flags, also available on CalendarCellContext. Check out the CocoaDocs generated documentation, or the class header for more.

Calendar Events

CalendarEvent is a simple data structure class which holds a title, a date, and an info dictionary. The calendar view will display automatically display CalendarEvent objects as passed to it by its data sourcee. If you have custom information that you want to show in a detail view, you can attach it to the event's info property.

As of MBCalendarKit 2.1.0, there's a color property as well. Setting it will cause the cell to display a colored "tag" in the cell. This feature should be considered experimental for now.

Customizing the First Day of the Week:

Version 2.2.0 adds support for the firstWeekday property of NSCalendar. If the currentCalendar (or whichever you set) has some day other than Sunday set as the first day of the week, the calendar view will respect that.

/// Instantiate a CalendarViewController or CalendarView.
let calendarViewController = CKCalendarViewController()

/// Set the first day of the week to Monday.
calendarViewController.calendarView.firstWeekDay = 2

About the firstWeekDay property: Use integers 1-7 to set a weekday from Sunday through Saturday. NSCalendar doesn't say what happens if you use another number, so you're on your own if you do that.

Animating Week Transitions

As of MBCalendarKit 5.0.0, CalendarView has a animatesWeekTransitions property which can be turned on to enable animated transitions in week mode.


Addendum

Thanks

Dave DeLong, for being an invaluable reference. Thanks to the folks on the iOS Folks Slack team for guidance on nullability and input on working around floating point division precision.

Thank you to the various contributors for patches and reporting issues.

Want to Contribute?

Learn more about contributing by clicking here.

Code Of Conduct

MBCalendarKit adopts the Contributor Covenant Code of Conduct. Read it here.

License

MBCalendarKit is hereby released under the MIT License. See LICENSE for details.

Like This?

If you like MBCalendarKit, check out some of my other projects:

Comments
  • CKCalendarView appearing behind iOS 7 status bar

    CKCalendarView appearing behind iOS 7 status bar

    This is a similar issue to having a UITableView on a UIView in iOS 7, where the UITableView starts too high and is behind the status bar. When I put a CKCalendarView on a UIView, the calendar starts behind the status bar, too. I can't seem to figure out a way of pushing it down by 64-pixels to be in the correct place. Is there something I'm missing?

    CKCalendarView Issue

    bug 
    opened by ed-parry 21
  • Crash - Xcode 7.1.1 Demo App

    Crash - Xcode 7.1.1 Demo App

    while running demo app (objective C ) app is not even opening. I commented all setDelegate functions then app is running but when i clicked on event it is not opening. Please help me.

    -[CKCalendarViewControllerInternal setDelegate:]: unrecognized selector sent to instance 0x14e62c6a0 2015-11-30 20:11:42.481 MBCalendarKit[861:168117] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CKCalendarViewControllerInternal setDelegate:]: unrecognized selector sent to instance 0x14e62c6a0'

    opened by sairamkotha 19
  • Swipe to change Months and weeks

    Swipe to change Months and weeks

    Hello,

    I'm using this calendarKit it was awesome and i had a problem on the following can you please help.

    • is there any way to swipe to change months in month view and swipe to change weeks on week view ?
    • how can i customise the event displaying as a single DOT but here i want to change to number of dots based on events count ?

    Thanks, Narendra V

    opened by narendra-ct 13
  • The fresh created calendarView is cut at the very top

    The fresh created calendarView is cut at the very top

    Modally presented ViewController, the only thing is done - in viewDidLoad method added the CalendarView. As you can see (see photo attached) - the top line of numbers is cut. Seems like it is added to the view without respect of TopLayoutGuide... at least I assume so.

    screen shot 2017-08-16 at 20 59 06 bug duplicate Auto Layout 5.0.x 
    opened by iChernov 11
  • Added ability to display images in the table for the selected date

    Added ability to display images in the table for the selected date

    Added an image property to the CKCalendarEvent class along with a corresponding constructor.

    Modified CKCalendarView such that if an event has a non-nil image it will display the image in the table for the selected date.

    opened by bhancock4 11
  • CalendarView doesn't take in account firstDayOfWeek

    CalendarView doesn't take in account firstDayOfWeek

    Summary

    CalendarView doesn't take in account firstDayOfWeek, so if (like in EU) first day of the week is Monday, then some months (like October 2017) are shown without the first day (as it is Sunday and it is hidden in the previous month's last line).

    Steps To Reproduce

    1. Set calendarView locale as "de_DE" or "ru_RU" and open October 2017

    Expected Results

    The whole month should be shown at once

    Actual Results

    Month is shown starting 2nd of October, but one extra line (with only November dates) is added at the end.

    Notes

    Please let me know where I can fix it. Very annoying bug.

    bug 5.1.0 
    opened by iChernov 10
  • Request for delegate - `(void)calendarView:(CKCalendarView *)CalendarView eventsDidLoad;`

    Request for delegate - `(void)calendarView:(CKCalendarView *)CalendarView eventsDidLoad;`

    In some cases with lot of events, it's taking almost 45 seconds after selecting a date before the events for that date show. This is a problem, as the last date's events are still in the table...

    So, after the user selects a date, I create a progress indicator and start it spinning using - (void)calendarView:(CKCalendarView *)CalendarView didSelectDate:(NSDate *)date; I would like to remove the spinner when the events list is finished populating. Maybe a delegate called (void)calendarView:(CKCalendarView *)CalendarView eventsDidLoad; ?

    Is there already a hook someplace for this?

    opened by bci 10
  • Feature Request: Method to change the dot color

    Feature Request: Method to change the dot color

    Can be part of CKCalendarDataSource.h:

    - (UIColor *)calendarView:(CKCalendarView *)calendarView dotColorForDate:(NSDate *)date;
    

    I'll try this (and maybe calendarView:labelColorForDate, and calendarView:backgroundColorForDate), I need to learn more ;) I'm just afraid the code will not be as clean...

    opened by bci 10
  • Problem when showing the calendar on iPhone 6s Plus not in Simulator

    Problem when showing the calendar on iPhone 6s Plus not in Simulator

    I have an issue that the first row of days in the monthly view is not showing up, in Simulator it works fine but on my device it's not as below screenshots: This is the simulator: ok

    And this is on my phone: not

    Any ideas?

    bug Auto Layout 5.1.0 
    opened by magcp 9
  • Ability to customize colors, fonts, dots, header.

    Ability to customize colors, fonts, dots, header.

    For README.md:

    How to customize colors, fonts, dots, header (still will need to figure out a better way):

    1. pod update (or install)
    2. Manually override macros defined in Pods/MBCalendarKit/CKCalendarHeaderColors.h andPods/MBCalendarKit/CKCalendarCellColors.h``
    3. Note your changes down somewhere else as updating pods will erase your changes obviously.

    GOTCHA: If running standalone demo project, you must add the required Frameworks (cited in the Podspec) to the CKCalendarKitTests target.

    opened by seenickcode 9
  • Customizing colors?

    Customizing colors?

    I see that you are customizing the colors via #define statements but is there a way to override those with your own? I tried #undef and that didnt' work. Thanks.

    opened by seenickcode 9
  • Tab Bar Text...

    Tab Bar Text...

    Hello,

    Is there a way to remove the tab bar text? Initially there is not text, but when the tube is first selected that display changes to show the icon and the word "Calendar" next to the tab bar button.

    Ideally I would like to remove the text.

    opened by DevStreamLine 0
  • Calendar week view - pressing forwards/backwards buttons sometimes skips a week

    Calendar week view - pressing forwards/backwards buttons sometimes skips a week

    Describe the bug While implementing MBCalendarKit in my project and using a week view, I noticed a bug - where sometimes pressing next/previous buttons (to switch to forwards/backwards week), it sometimes skips a week.

    To Reproduce I could easily reproduce this problem using provided demo. In Objective-C Calendar Control -> week view and Animated Week Transitions.

    Steps to reproduce the behaviour skipping a week when pressing next button:

    1. Open a week view
    2. Click on the LAST date of the visible week (and notice the date)
    3. Press next button
    4. See that visibly a week has been skipped

    Steps to reproduce the behaviour skipping a week when pressing previous button:

    1. Open a week view
    2. Click on the FIRST date of the visible week (and notice the date)
    3. Press previous button
    4. See that visibly a week has been skipped

    The issue is not reproducable, if, before pressing any button - first/last date is not selected.

    Expected behavior I would expect a week not to be skipped.

    Additional context Tested on iPhone 7, iOS 12

    Possible fixes I found a possible solution that works for me.

    For backward button, I added an extra code before this line:

    https://github.com/MosheBerman/MBCalendarKit/blob/9c46b80071c27bbec5a719d901f343dfc3dc2e02/MBCalendarKit/CalendarKit/Core/CKCalendarModel%2BHeaderViewSupport.m#L276

    Code: date = [self.calendar lastDayOfTheWeekUsingReferenceDate:date]; (Basically I set the date as the last day of the visible week, thus making sure that a week will not be skipped)

    For forward button, I added an extra code before this line:

    https://github.com/MosheBerman/MBCalendarKit/blob/9c46b80071c27bbec5a719d901f343dfc3dc2e02/MBCalendarKit/CalendarKit/Core/CKCalendarModel%2BHeaderViewSupport.m#L198

    Code: date = [self.calendar firstDayOfTheWeekUsingReferenceDate:date]; (Basically I set the date as the first day of the visible week, thus making sure that a week will not be skipped)

    opened by GuntisTreulands 0
  • How to achieve calendar color customization?

    How to achieve calendar color customization?

    Hi @MosheBerman ,

    I have tried to change colors in CKCalendarCellColors.h and have also tried to change it from applyColorsForState function in CKCalendarCell but, it is not getting change.

    Can you please suggest how can I do this?

    opened by NeenaMishra12 1
  • Changed it to NSCalendarIdentifierIslamic not working

    Changed it to NSCalendarIdentifierIslamic not working

    I changed it type to islamic in viewDidLoad of subclass of CKCalendarViewController.

    here is my code

    NSCalendar *islamicCalender = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierIslamic]; [self.calendarView setCalendar:islamicCalender]; [self.calendarView reload];

    but it does't allow me to update after 2 times right button pressed for next month.and it stucks.

    opened by shoaibhassanWhizpool 0
  • Hello Project's Owner

    Hello Project's Owner

    I have a question for this library. Because, I cannot display the calendar event in my app. I want to show which when click on the date (Week mode). But, I cannot display it. You can contact me by:

    Thanks and Regard.

    opened by iVoGia 0
Releases(5.2.3)
Owner
Moshe
Self-care, family, code.
Moshe
RCalendarPicker A date picker control, Calendar calendar control, select control, calendar, date selection, the clock selection control.

RCalendarPicker RCalendarPicker Calendar calendar control, select control, calendar, date selection, the clock selection control. 日历控件 ,日历选择控件,日历,日期选择

杜耀辉 131 Jul 18, 2022
Malendar is a personal calendar app that connects to your default calendar and lets you add/delete events

Malendar is a personal calendar app that connects to your default calendar and lets you add/delete events. It will gather events from your default iOS calendar.

Chase 194 Jan 4, 2023
A declarative, performant, iOS calendar UI component that supports use cases ranging from simple date pickers all the way up to fully-featured calendar apps.

HorizonCalendar A declarative, performant, calendar UI component that supports use cases ranging from simple date pickers all the way up to fully-feat

Airbnb 2.2k Jan 4, 2023
Simple customizable calendar component in Swift :calendar:

Koyomi Koyomi is a simple calendar view framework for iOS, written in Swift ?? Content Features Demo App Usage introduction : Change displayed month,

Shohei Yokoyama 741 Dec 24, 2022
An iOS pre-permissions utility that lets developers ask users on their own dialog for calendar, contacts, location, photos, reminders, twitter, push notifications and more, before making the system-based permission request.

An iOS pre-permissions utility that lets developers ask users on their own dialog for calendar, contacts, location, photos, reminders, twitter, push notifications and more, before making the system-based permission request.

Joe L 420 Dec 22, 2022
CrispyCalendar is the calendar UI framework you need

Whether you are writing yet another one task tracker or calendar app, or simply want to offer the users to skip the joy of using UIDatePicker and let them quickly and efficiently select dates — CrispyCalendar is the calendar UI framework you need.

CleverPumpkin 315 Aug 12, 2022
An Event View based on Apple's Event Detail View. Written in Swift 3. Supports ARC, Autolayout and editing via StoryBoard.

An Event View based on Apple's Event Detail View. Written in Swift 3. Supports ARC, Autolayout and editing via StoryBoard. Installation CocoaPods PTEv

Aman Taneja 36 Oct 5, 2022
Calendar View - It's lightweight and simple control with supporting Locale and CalendarIdentifier.

iOS Calendar It's lightweight and simple control with supporting Locale and CalendarIdentifier. There're samples for iPhone and iPad, and also with us

Maksym Bilan 159 Dec 22, 2022
📅 Calendar for iOS, iPadOS and macOS in Swift

CalendarKit CalendarKit is a Swift calendar UI library for iOS, iPadOS and Mac Catalyst. It looks similar to the Apple Calendar app out-of-the-box, wh

Richard Topchii 2.2k Jan 5, 2023
A fully customizable iOS calendar library, compatible with Objective-C and Swift

Table of contents Screenshots Installation Pre-knowledge Support Contact Screenshots iPhone iPad Safe Orientation Today Extension iOS8/9 iOS10 Interac

Wenchao Ding 10.2k Jan 2, 2023
A library that expresses a github contribution calendar through an array of dates. Supports iOS and macOS.

A library that expresses a github contribution calendar through an array of dates. Supports iOS and macOS.

jasu 45 Dec 20, 2022
CalendarApp Swift - Made a calendar app in swift, completely from scratch using UIStackView and UICollectionView

CalendarApp_Swift Made a calendar app in swift, completely from scratch using UI

Arnav Chhokra 1 Feb 4, 2022
A SwiftUI calendar view that allows month switching and date picking.

Selectable Calendar View A SwiftUI calendar view that allows month switching and date picking. Usage You can simply add this repository to your projec

シュンジョーァ 10 Jul 21, 2022
An Easy to Use Calendar for iOS (Swift 5.0)

This is an easy to use, "just drag and drop it in your code" type of calendar for iOS. It supports both vertical and horizontal scrolling, as well as

Michael Michailidis 525 Dec 23, 2022
SwiftUI Simple Calendar / Date Picker for iOS

RKCalendar RKCalendar is a SwiftUI Calendar / Date Picker for iOS. Features include: minimum and maximum calendar dates selectable, single date select

null 453 Dec 28, 2022
A custom visual calendar for iOS 8+ written in Swift (>= 4.0).

Overview Screenshots GIF Demo Installation Usage Architecture Version matrix Advanced API For contributors Screenshots GIF Demo Installation CocoaPods

null 3.5k Dec 24, 2022
iOS 7+ Calendar (Date Picker) with Infinite Scrolling.

RSDayFlow iOS 7 Calendar with Infinite Scrolling. Only need 4 lines of code to set up. RSDayFlow is a slim fork of DayFlow with updates and extensions

Ruslan Skorb 844 Sep 14, 2022
An availability calendar implementation for iOS

NWCalendarView NWCalendar View is an iOS control that displays a calendar. It is perfect for appointment or availibilty selection. It allows for selec

Nicholas Wargnier 60 May 27, 2021
A customizable calendar view for iOS.

JTCalendar JTCalendar is an easily customizable calendar control for iOS. Installation With CocoaPods, add this line to your Podfile. pod 'JTCalendar'

Jonathan Vukovich-Tribouharet 2.8k Dec 27, 2022