A customizable calendar view for iOS.

Related tags

Calendar ios calendar
Overview

JTCalendar

CI Status Version Carthage compatible License Platform

JTCalendar is an easily customizable calendar control for iOS.

Installation

With CocoaPods, add this line to your Podfile.

pod 'JTCalendar', '~> 2.0'

Carthage

To use this project with Carthage, add this line to your Cartfile.

github "jonathantribouharet/JTCalendar" ~> 2.2

Screenshots

Example Example

Warning

The part below the calendar in the 2nd screenshot is not provided.

Features

  • horizontal and vertical calendar
  • highly customizable either by subclassing default class provided or by creating your own class implementing a protocol
  • support internationalization
  • week view mode
  • limited range, you can define a start and an end to you calendar

Usage

Basic usage

You have to create two views in your UIViewController:

  • The first view is JTCalendarMenuView and it represents the part with the months names. This view is optional.
  • The second view is JTHorizontalCalendarView or JTVerticalCalendarView, it represents the calendar itself.

Your UIViewController have to implement JTCalendarDelegate, all methods are optional.

#import <UIKit/UIKit.h>

#import <JTCalendar/JTCalendar.h>

@interface ViewController : UIViewController<JTCalendarDelegate>

@property (weak, nonatomic) IBOutlet JTCalendarMenuView *calendarMenuView;
@property (weak, nonatomic) IBOutlet JTHorizontalCalendarView *calendarContentView;

@property (strong, nonatomic) JTCalendarManager *calendarManager;

@end

JTCalendarManager is used to coordinate calendarMenuView and calendarContentView and provide a default behavior.

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
        
    _calendarManager = [JTCalendarManager new];
    _calendarManager.delegate = self;
    
    [_calendarManager setMenuView:_calendarMenuView];
    [_calendarManager setContentView:_calendarContentView];
    [_calendarManager setDate:[NSDate date]];
}

@end

The Example project contains some use cases you may check before asking questions.

Advanced usage

Even if all methods of JTCalendarManager are optional you won't get far without implementing at least the two next methods:

  • calendar:prepareDayView: this method is used to customize the design of the day view for a specific date. This method is called each time a new date is set in a dayView or each time the current page change. You can force the call to this method by calling [_calendarManager reload];.
- (void)calendar:(JTCalendarManager *)calendar prepareDayView:(JTCalendarDayView *)dayView
{
    dayView.hidden = NO;
    
    // Test if the dayView is from another month than the page
    // Use only in month mode for indicate the day of the previous or next month
    if([dayView isFromAnotherMonth]){ 
        dayView.hidden = YES;
    }
    // Today
    else if([_calendarManager.dateHelper date:[NSDate date] isTheSameDayThan:dayView.date]){
        dayView.circleView.hidden = NO;
        dayView.circleView.backgroundColor = [UIColor blueColor];
        dayView.dotView.backgroundColor = [UIColor whiteColor];
        dayView.textLabel.textColor = [UIColor whiteColor];
    }
    // Selected date
    else if(_dateSelected && [_calendarManager.dateHelper date:_dateSelected isTheSameDayThan:dayView.date]){
        dayView.circleView.hidden = NO;
        dayView.circleView.backgroundColor = [UIColor redColor];
        dayView.dotView.backgroundColor = [UIColor whiteColor];
        dayView.textLabel.textColor = [UIColor whiteColor];
    }
    // Another day of the current month
    else{
        dayView.circleView.hidden = YES;
        dayView.dotView.backgroundColor = [UIColor redColor];
        dayView.textLabel.textColor = [UIColor blackColor];
    }
    
    // Your method to test if a date have an event for example
    if([self haveEventForDay:dayView.date]){
        dayView.dotView.hidden = NO;
    }
    else{
        dayView.dotView.hidden = YES;
    }
}
  • calendar:didTouchDayView: this method is used to respond to a touch on a dayView. For example you can indicate to display another month if dayView is from another month.
- (void)calendar:(JTCalendarManager *)calendar didTouchDayView:(JTCalendarDayView *)dayView
{
    // Use to indicate the selected date
    _dateSelected = dayView.date;
    
    // Animation for the circleView
    dayView.circleView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.1, 0.1);
    [UIView transitionWithView:dayView
                      duration:.3
                       options:0
                    animations:^{
                        dayView.circleView.transform = CGAffineTransformIdentity;
                        [_calendarManager reload];
                    } completion:nil];
    
    // Load the previous or next page if touch a day from another month
    if(![_calendarManager.dateHelper date:_calendarContentView.date isTheSameMonthThan:dayView.date]){
        if([_calendarContentView.date compare:dayView.date] == NSOrderedAscending){
            [_calendarContentView loadNextPageWithAnimation];
        }
        else{
            [_calendarContentView loadPreviousPageWithAnimation];
        }
    }
}

Switch to week view

If you want see just one week at a time, you have to set the isWeekMode to YES and reload the calendar.

_calendarManager.settings.weekModeEnabled = YES;
[_calendarManager reload];

WARNING

When you change the mode, it doesn't change the height of calendarContentView, you have to do it yourself. See the Example project for more details.

Customize the design

For customize the design you have to implement some methods depending of what parts you want to custom. Check the JTCalendarDelegate file and the Example project.

For example:

// This method is independent from the date, it's call only at the creation of the dayView.
// For customize the dayView depending of the date use `prepareDayView` method
- (UIView<JTCalendarDay> *)calendarBuildDayView:(JTCalendarManager *)calendar
{
    JTCalendarDayView *view = [JTCalendarDayView new];
    view.textLabel.font = [UIFont fontWithName:@"Avenir-Light" size:13];
    view.textLabel.textColor = [UIColor blackColor];
    
    return view;
}

Pagination

The content views (JTHorizontalCalendarView and JTVerticalCalendarView) are just subclass of UIScrollView. Each time the current page change, calendarDidLoadNextPage or calendarDidLoadPreviousPage is called. The content views provide two method for display the previous or next page with an animation loadNextPageWithAnimation and loadPreviousPageWithAnimation. You can limit the range of the calendar by implementing canDisplayPageWithDate method.

// Used to limit the date for the calendar
- (BOOL)calendar:(JTCalendarManager *)calendar canDisplayPageWithDate:(NSDate *)date
{
    return [_calendarManager.dateHelper date:date isEqualOrAfter:_minDate andEqualOrBefore:_maxDate];
}

Vertical calendar

If you use JTVerticalCalendarView for having a vertical calendar, you have some settings you have to set.

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    _calendarManager = [JTCalendarManager new];
    _calendarManager.delegate = self;
    
    _calendarManager.settings.pageViewHaveWeekDaysView = NO; // You don't want WeekDaysView in the contentView
    _calendarManager.settings.pageViewNumberOfWeeks = 0; // Automatic number of weeks
    
    _weekDayView.manager = _calendarManager; // You set the manager for WeekDaysView
    [_weekDayView reload]; // You load WeekDaysView manually

    [_calendarManager setMenuView:_calendarMenuView];
    [_calendarManager setContentView:_calendarContentView];
    [_calendarManager setDate:[NSDate date]];
    
    _calendarMenuView.scrollView.scrollEnabled = NO; // The scroll is not supported with JTVerticalCalendarView
}

Internationalization / Localization (change first weekday)

For changing the locale and the timeZone just do:

_calendarManager.dateHelper.calendar.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"CDT"];
_calendarManager.dateHelper.calendar.locale = [NSLocale localeWithLocaleIdentifier:@"fr_FR"];
[_calendarManager reload];

For changing locale and timeZone in Swift use:

let locale = Locale(identifier: "fr_FR")
let timeZone = TimeZone.init(abbreviation: "CDT")
calendarManager = JTCalendarManager(locale: locale, andTimeZone: timeZone)

Date comparaison

Be careful when you compare two different dates, you have to take care of the time zone. An helper is provided for some basic operations:

[_calendarManager.dateHelper date:dateA isTheSameMonthThan:dateB];
[_calendarManager.dateHelper date:dateA isTheSameWeekThan:dateB];
[_calendarManager.dateHelper date:dateA isTheSameDayThan:dateB];

// Use to limit the calendar range
[_calendarManager.dateHelper date:date isEqualOrAfter:minDate andEqualOrBefore:maxDate];

Optimization

Every methods in the delegate are called in the main thread, you have to be really careful, in particular in the prepareDayView method which is called very often.

If you have to fetch some data from something slow, I recommend to create a cache and query this cache in prepareDayView method. You have to cache the data from the next pages and update this cache asynchronously (in another thread via dispatch_async) when a new page is loaded (via calendarDidLoadNextPage and calendarDidLoadPreviousPage methods).

Questions

Before asking any questions be sure to explore the Example project. Check also JTCalendarDelegate and JTCalendarSettings files.

Don't use NSLog to print date use a NSDateFormatter, NSLogdoesn't take care of the timezone.

NSDateFormatter *dateFormatter = [_calendarManager.dateHelper createDateFormatter];
dateFormatter.dateFormat = @"yyyy'-'MM'-'dd' 'HH':'mm':'ss";
NSLog(@"%@", [dateFormatter stringFromDate:yourDate]);

Requirements

  • iOS 7 or higher
  • Automatic Reference Counting (ARC)

Author

License

JTCalendar is released under the MIT license. See the LICENSE file for more info.

Comments
  • Calendar ReloadData issue

    Calendar ReloadData issue

    I am having an issue with the calendar reloading after the view is presented. For example, right now it shows October then scrolls to the current month of December. I don't see this issue with the example app, but I also don't see any differences in my code from the example.

    opened by sbrines 13
  • Vertical layout miss some days at the beginning or the and of the month

    Vertical layout miss some days at the beginning or the and of the month

    Vertical layout, english locale, but applies also with italian. A lot of times it misses the first day of the month or the last days. Tested only on simulator, iOS8, Xcode 6.4. Here is a screen: ios simulator screen shot 21 lug 2015 09 08 01

    opened by DrAma999 11
  • scrollView inside JTCalendarMenuView not being initialized properly.

    scrollView inside JTCalendarMenuView not being initialized properly.

    I am having problem with JYCalendarMenuView.

    It crashes when the view is loading. I am not sure what code to share except that the viewcontroller is being pushed from a uinavigationcontroller using storyboards.

    Here's what I got when i Po'd.

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        //[_manager.scrollManager updateHorizontalContentOffset:(_scrollView.contentOffset.x / _scrollView.contentSize.width)];
        if (_scrollView.contentSize.width == 0) {
    
        } else {
        [_manager.scrollManager updateHorizontalContentOffset:(_scrollView.contentOffset.x / _scrollView.contentSize.width)];
        }
    
    }
    
    opened by franciszabala 9
  • add alpha animation for menu month view

    add alpha animation for menu month view

    Hi, @jonathantribouharet I add a alpha animation effect on the month menu view. The more the menu is close to the center of the screen, the greater the alpha is. I also leave a interface for setting the max alpha value and the min.This is the effect PR #52

    jtcalendar-alpha

    opened by WenchaoD 9
  • JTCalendarDayView selection API

    JTCalendarDayView selection API

    Hello Jonathan,

    Thank you for such a nice calendar. It might be even better, if there was an explicit way of selecting a date (simple adding a CircleView onto the day one). I hope you find this feature useful to work on.

    Thank you and happy coding time! :+1:

    opened by mozharovsky 9
  • UTC Date / selection of current date / today

    UTC Date / selection of current date / today

    I'm trying to select the first day of the month once the month page (next / previous) has changed.

    I have a UTC date which is the first of the month, but the selection doesn't appear the filled red circle. Also I'd expect if I clicked today that it showed that, instead of the blue filled circle.

    My local time zone is British Summer Time, however I would expect that the date section obeys this and not UTC. I know that NSDate uses UTC, however I'm a little confused about the whole area. But my users could be in any time zone and I'd expect their current date or today to work with the red filled circle.

    Here's my code.

    Thanks for your control and doing such a great job, I've almost got my solution working :)

    opened by JulesMoorhouse 8
  • How do i integrate this JTCalendar to my existing project??? please help

    How do i integrate this JTCalendar to my existing project??? please help

    I have created a new project and i wanna show JTCalendar over there(UIViewController - storyboard) How do implement that?? when i tried it showing this error

    Undefined symbols for architecture arm64: "OBJC_CLASS$_JTCalendar",

    opened by nnaavveenn35 8
  • How to create event with NSDate

    How to create event with NSDate

    Hi developer;
    I'm a developer as well, and I'm trying to implement inside JTCalendar some event taken from NsDate*dateSelected

    In it I've some date in "dd/MM/yyyy HH:mm":

    NSLog(@"%@",dateselected) "2014-12-09 00:05:41.908 Database Demo[1348:31927] 2014-12-09 09:39:37 +0000 2014-12-09 00:05:41.911 Database Demo[1348:31927] 2014-12-14 09:32:26 +0000 2014-12-09 00:05:41.913 Database Demo[1348:31927] 2014-12-20 08:08:09 +0000"

    When I try to implement the date of "dateSelected" in the eventsByDate[key], it makes just one event (the last one that I've insert in the dateSelected).

    Here the code:

    • (void)createEvents { eventsByDate = [NSMutableDictionary new];

      NSDate *myDate = dateSelected;
      
      NSString *key = [[self dateFormatter] stringFromDate:myDate];
      
      if(!eventsByDate[key]){
          eventsByDate[key] = [NSMutableArray new];
      }
      
      [eventsByDate[key] addObject:myDate];
      }
      

      }

    Can you help me ???

    Have a nice day......;)

    opened by SwiftySrl 8
  • Multiple calendar views in a view controller will update selected day simultaneously

    Multiple calendar views in a view controller will update selected day simultaneously

    I have a form which takes in a start and end date. Both the start and end dates use the calendar view. When I touch a day on one of the calendars, the day is selected on both calendars (due to the method didDaySelected:(NSNotification *)notification getting called). Is there any way to reload the current day selected?

    opened by dfithian 7
  • Selecting the 1st date of every month when navigating to another month

    Selecting the 1st date of every month when navigating to another month

    I'm not using the JTCalendarMenuView in my app due to space constraints. Instead I show the selected date on the navigation bar of my app. Is there anyway to mimic the stock iOS calendar app behavior ? That is, when you swipe to another month, the selected date changes to the 1st of that month.

    opened by ghost 7
  • Incorrect start date

    Incorrect start date

    Hi, amazing repo.

    Using the code from the Example project, my calendar starts in October 2014. Any Idea why this is happening and how I can fix it?

    Code below;

    // Calendar Setup
    self.calendar = [JTCalendar new];
    // All modifications on calendarAppearance have to be done before setMenuMonthsView and setContentView
    // Or you will have to call reloadAppearance
    {
        self.calendar.calendarAppearance.calendar.firstWeekday = 2; // Sunday == 1, Saturday == 7
        self.calendar.calendarAppearance.dayCircleRatio = 9. / 10.;
        self.calendar.calendarAppearance.ratioContentMenu = 2.;
    
        self.calendar.calendarAppearance.monthBlock = ^NSString *(NSDate *date, JTCalendar *jt_calendar){
            NSCalendar *calendar = jt_calendar.calendarAppearance.calendar;
            NSDateComponents *comps = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth fromDate:date];
            NSInteger currentMonthIndex = comps.month;
    
            static NSDateFormatter *dateFormatter;
            if(!dateFormatter){
                dateFormatter = [NSDateFormatter new];
                dateFormatter.timeZone = jt_calendar.calendarAppearance.calendar.timeZone;
            }
    
            while(currentMonthIndex <= 0){
                currentMonthIndex += 12;
            }
    
            NSString *monthText = [[dateFormatter standaloneMonthSymbols][currentMonthIndex - 1] capitalizedString];
    
            return [NSString stringWithFormat:@"%ld\n%@", (long)comps.year, monthText];
        };
    }
    
    [self.calendar setMenuMonthsView:self.calendarMenuView];
    [self.calendar setContentView:self.calendarContentView];
    [self.calendar setDataSource:self];
    
    opened by moh-abk 7
  • Add ability to inject custom calendar with backward compatibility

    Add ability to inject custom calendar with backward compatibility

    Issue : I needed to update few calendar's property e.g. firstWeekday, because JTDateHelper was returning non mutable calendar object , i was not able to do so.

    Solution proposing As JTDateHelper is having three instance variable , NSCalendar, NSLocale and NSTimeZone, but only 2 are available to inject. There can always be a need to update some properties of NSCalendar and hence I added ability to inject full calendar object itself with maintaining the backward compatibility of current code.

    opened by nitinkraghuwanshi 0
  • Type Mismatch: Signed to Unsigned

    Type Mismatch: Signed to Unsigned

    We have used JTCalendar as per our need. Some VAPT points are mentioned in below picture. Kindly help us asap.

    Issue Summary: The function numberOfWeeks:() in JTDateHelper.m is declared to return an unsigned value, but on line 77 it returns a signed value.The function is declared to return an unsigned number but returns a signed value.

    Issue Screenshot: Screenshot 2019-12-25 at 10 14 36 AM

    opened by gopalchinnadurai 0
  • Need changes in week view

    Need changes in week view

    This is my current problem: Untitled

    I need to change in week view, Like I need Monday on the very first of view and rest as continuos. I could not able to do it through the library and also can't able to find any Questions regarding this. Also, need to change in the text whether the default is coming with three characters and I need only a single character.

    Apart from that I also need to change the color of the whole week's view. text color is fine but I need to change the view's color.

    I'm adding an image below exactly what I want.

    Like this below photo: Untitled

    opened by ravindra1191 0
  • Not scrolling to today date.

    Not scrolling to today date.

    I am using this library from the beginning and now I came across the issue that it doesn't scroll to today's date. It just stops to previous month's date. Anyone have this issue? Following code I have used.

    `func setupJTCalendar() { self.dayCollectionView.cellSize = 60.0 self.dayCollectionView.minimumLineSpacing = 0 self.dayCollectionView.minimumInteritemSpacing = 0 self.dayCollectionView.scrollToDate(Date()) self.dayCollectionView.selectDates([Date()])

        self.dayCollectionView.visibleDates { (info) in
            if let data =  info.monthDates.first {
                self.dayCollectionView.scrollToItem(at: data.indexPath, at: .left, animated: true)
            }
        }
    }`
    
    opened by NirajCapermint 1
Owner
Jonathan Vukovich-Tribouharet
Founder and CEO @Yokitup
Jonathan Vukovich-Tribouharet
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
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
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 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
A fully customizable calendar view acting as a date range picker

Demo Installation CocoaPods With CocoaPods you can simply add GLCalendarView in your Podfile: pod "GLCalendarView", "~> 1.0.0" Source File You can co

Glow Inc 860 Nov 18, 2022
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 customizable swiftui calendar

Description not available. Installation From Xcode 11, you can use Swift Package Manager to add Kingfisher to your project. Select File > Swift Packag

Heshan Yodagama 140 Dec 24, 2022
A calendar quick view for the MacOS status bar

Calendar Quick View Quick Menu Calendar in the mac app store An open source macOS calendar preview utility Download from the Mac App Store Visualizati

Michaellis 18 Oct 26, 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
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
📅 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
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
📆 An elegant calendar control for iOS.

NO LONGER MAINTAINED Daysquare An elegant calendar control for iOS. Introduction Get bored with native silly UIDatePicker? You may have a try on this

Cyandev 701 Sep 9, 2022
A calendar control for iOS written in swift with mvvm pattern

ASCalendar try it on appetize Installation CocoaPods You can use CocoaPods to install ASCalendar by adding it to your Podfile: platform :ios, '8.0' us

Alberto Scampini 192 Jun 26, 2022
An open source calendar framework for iOS, with support for customization, IBDesignable, Autolayout, and more.

About MBCalendarKit is a calendar control written in Objective-C with modern best practices and Swift interoperability in mind. It offers a flexible c

Moshe 563 Oct 27, 2022