{"id":15026598,"url":"https://github.com/johnvuko/jtcalendar","last_synced_at":"2025-05-15T05:07:36.313Z","repository":{"id":22593758,"uuid":"25935703","full_name":"johnvuko/JTCalendar","owner":"johnvuko","description":"A customizable calendar view for iOS.","archived":false,"fork":false,"pushed_at":"2021-12-06T16:23:29.000Z","size":782,"stargazers_count":2763,"open_issues_count":118,"forks_count":532,"subscribers_count":93,"default_branch":"master","last_synced_at":"2025-05-15T05:07:26.104Z","etag":null,"topics":["calendar","ios"],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnvuko.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-10-29T18:39:06.000Z","updated_at":"2025-04-18T08:17:53.000Z","dependencies_parsed_at":"2022-08-07T10:15:55.570Z","dependency_job_id":null,"html_url":"https://github.com/johnvuko/JTCalendar","commit_stats":null,"previous_names":["johnvuko/jtcalendar"],"tags_count":62,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnvuko%2FJTCalendar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnvuko%2FJTCalendar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnvuko%2FJTCalendar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnvuko%2FJTCalendar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnvuko","download_url":"https://codeload.github.com/johnvuko/JTCalendar/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254276447,"owners_count":22043867,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calendar","ios"],"created_at":"2024-09-24T20:04:45.214Z","updated_at":"2025-05-15T05:07:31.298Z","avatar_url":"https://github.com/johnvuko.png","language":"Objective-C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JTCalendar\n\n[![CI Status](http://img.shields.io/travis/jonathantribouharet/JTCalendar.svg)](https://travis-ci.org/jonathantribouharet/JTCalendar)\n![Version](https://img.shields.io/cocoapods/v/JTCalendar.svg)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n![License](https://img.shields.io/cocoapods/l/JTCalendar.svg)\n![Platform](https://img.shields.io/cocoapods/p/JTCalendar.svg)\n\nJTCalendar is an easily customizable calendar control for iOS.\n\n## Installation\n\nWith [CocoaPods](http://cocoapods.org), add this line to your Podfile.\n\n    pod 'JTCalendar', '~\u003e 2.0'\n\n### Carthage\n\nTo use this project with [Carthage](https://github.com/Carthage/Carthage), add this line to your Cartfile.\n\n    github \"jonathantribouharet/JTCalendar\" ~\u003e 2.2\n\n## Screenshots\n\n![Example](./Screens/example.gif \"Example View\")\n![Example](./Screens/example.png \"Example View\")\n\n### Warning\n\nThe part below the calendar in the 2nd screenshot is not provided.\n\n## Features\n\n- horizontal and vertical calendar\n- highly customizable either by subclassing default class provided or by creating your own class implementing a protocol\n- support internationalization\n- week view mode\n- limited range, you can define a start and an end to you calendar\n\n## Usage\n\n### Basic usage\n\nYou have to create two views in your `UIViewController`:\n\n- The first view is `JTCalendarMenuView` and it represents the part with the months names. This view is optional.\n- The second view is `JTHorizontalCalendarView` or `JTVerticalCalendarView`, it represents the calendar itself.\n\nYour `UIViewController` have to implement `JTCalendarDelegate`, all methods are optional.\n\n```objective-c\n#import \u003cUIKit/UIKit.h\u003e\n\n#import \u003cJTCalendar/JTCalendar.h\u003e\n\n@interface ViewController : UIViewController\u003cJTCalendarDelegate\u003e\n\n@property (weak, nonatomic) IBOutlet JTCalendarMenuView *calendarMenuView;\n@property (weak, nonatomic) IBOutlet JTHorizontalCalendarView *calendarContentView;\n\n@property (strong, nonatomic) JTCalendarManager *calendarManager;\n\n@end\n```\n\n`JTCalendarManager` is used to coordinate `calendarMenuView` and `calendarContentView` and provide a default behavior.\n\n```objective-c\n@implementation ViewController\n\n- (void)viewDidLoad\n{\n    [super viewDidLoad];\n        \n    _calendarManager = [JTCalendarManager new];\n    _calendarManager.delegate = self;\n    \n    [_calendarManager setMenuView:_calendarMenuView];\n    [_calendarManager setContentView:_calendarContentView];\n    [_calendarManager setDate:[NSDate date]];\n}\n\n@end\n\n```\n\nThe Example project contains some use cases you may check before asking questions.\n\n### Advanced usage\n\nEven if all methods of `JTCalendarManager` are optional you won't get far without implementing at least the two next methods:\n- `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];`.\n\n\n```objective-c\n- (void)calendar:(JTCalendarManager *)calendar prepareDayView:(JTCalendarDayView *)dayView\n{\n    dayView.hidden = NO;\n    \n    // Test if the dayView is from another month than the page\n    // Use only in month mode for indicate the day of the previous or next month\n    if([dayView isFromAnotherMonth]){ \n        dayView.hidden = YES;\n    }\n    // Today\n    else if([_calendarManager.dateHelper date:[NSDate date] isTheSameDayThan:dayView.date]){\n        dayView.circleView.hidden = NO;\n        dayView.circleView.backgroundColor = [UIColor blueColor];\n        dayView.dotView.backgroundColor = [UIColor whiteColor];\n        dayView.textLabel.textColor = [UIColor whiteColor];\n    }\n    // Selected date\n    else if(_dateSelected \u0026\u0026 [_calendarManager.dateHelper date:_dateSelected isTheSameDayThan:dayView.date]){\n        dayView.circleView.hidden = NO;\n        dayView.circleView.backgroundColor = [UIColor redColor];\n        dayView.dotView.backgroundColor = [UIColor whiteColor];\n        dayView.textLabel.textColor = [UIColor whiteColor];\n    }\n    // Another day of the current month\n    else{\n        dayView.circleView.hidden = YES;\n        dayView.dotView.backgroundColor = [UIColor redColor];\n        dayView.textLabel.textColor = [UIColor blackColor];\n    }\n    \n    // Your method to test if a date have an event for example\n    if([self haveEventForDay:dayView.date]){\n        dayView.dotView.hidden = NO;\n    }\n    else{\n        dayView.dotView.hidden = YES;\n    }\n}\n```\n\n- `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.\n\n```objective-c\n- (void)calendar:(JTCalendarManager *)calendar didTouchDayView:(JTCalendarDayView *)dayView\n{\n    // Use to indicate the selected date\n    _dateSelected = dayView.date;\n    \n    // Animation for the circleView\n    dayView.circleView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.1, 0.1);\n    [UIView transitionWithView:dayView\n                      duration:.3\n                       options:0\n                    animations:^{\n                        dayView.circleView.transform = CGAffineTransformIdentity;\n                        [_calendarManager reload];\n                    } completion:nil];\n    \n    // Load the previous or next page if touch a day from another month\n    if(![_calendarManager.dateHelper date:_calendarContentView.date isTheSameMonthThan:dayView.date]){\n        if([_calendarContentView.date compare:dayView.date] == NSOrderedAscending){\n            [_calendarContentView loadNextPageWithAnimation];\n        }\n        else{\n            [_calendarContentView loadPreviousPageWithAnimation];\n        }\n    }\n}\n```\n\n### Switch to week view\n\nIf you want see just one week at a time, you have to set the `isWeekMode` to `YES` and reload the calendar.\n\n```objective-c\n_calendarManager.settings.weekModeEnabled = YES;\n[_calendarManager reload];\n```\n\n#### WARNING\n\nWhen you change the mode, it doesn't change the height of `calendarContentView`, you have to do it yourself.\nSee the Example project for more details.\n\n### Customize the design\n\nFor customize the design you have to implement some methods depending of what parts you want to custom. Check the [JTCalendarDelegate](JTCalendar/JTCalendarDelegate.h) file and the Example project.\n\nFor example:\n\n```objective-c\n// This method is independent from the date, it's call only at the creation of the dayView.\n// For customize the dayView depending of the date use `prepareDayView` method\n- (UIView\u003cJTCalendarDay\u003e *)calendarBuildDayView:(JTCalendarManager *)calendar\n{\n    JTCalendarDayView *view = [JTCalendarDayView new];\n    view.textLabel.font = [UIFont fontWithName:@\"Avenir-Light\" size:13];\n    view.textLabel.textColor = [UIColor blackColor];\n    \n    return view;\n}\n```\n\n### Pagination\n\nThe content views (`JTHorizontalCalendarView` and `JTVerticalCalendarView`) are just subclass of `UIScrollView`.\nEach time the current page change, `calendarDidLoadNextPage` or `calendarDidLoadPreviousPage` is called.\nThe content views provide two method for display the previous or next page with an animation `loadNextPageWithAnimation` and `loadPreviousPageWithAnimation`.\nYou can limit the range of the calendar by implementing `canDisplayPageWithDate` method.\n\n```objective-c\n// Used to limit the date for the calendar\n- (BOOL)calendar:(JTCalendarManager *)calendar canDisplayPageWithDate:(NSDate *)date\n{\n    return [_calendarManager.dateHelper date:date isEqualOrAfter:_minDate andEqualOrBefore:_maxDate];\n}\n```\n\n### Vertical calendar\n\nIf you use `JTVerticalCalendarView` for having a vertical calendar, you have some settings you have to set.\n\n```objective-c\n- (void)viewDidLoad\n{\n    [super viewDidLoad];\n    \n    _calendarManager = [JTCalendarManager new];\n    _calendarManager.delegate = self;\n    \n    _calendarManager.settings.pageViewHaveWeekDaysView = NO; // You don't want WeekDaysView in the contentView\n    _calendarManager.settings.pageViewNumberOfWeeks = 0; // Automatic number of weeks\n    \n    _weekDayView.manager = _calendarManager; // You set the manager for WeekDaysView\n    [_weekDayView reload]; // You load WeekDaysView manually\n\n    [_calendarManager setMenuView:_calendarMenuView];\n    [_calendarManager setContentView:_calendarContentView];\n    [_calendarManager setDate:[NSDate date]];\n    \n    _calendarMenuView.scrollView.scrollEnabled = NO; // The scroll is not supported with JTVerticalCalendarView\n}\n```\n\n### Internationalization / Localization (change first weekday)\n\nFor changing the locale and the timeZone just do:\n\n```objective-c\n_calendarManager.dateHelper.calendar.timeZone = [NSTimeZone timeZoneWithAbbreviation:@\"CDT\"];\n_calendarManager.dateHelper.calendar.locale = [NSLocale localeWithLocaleIdentifier:@\"fr_FR\"];\n[_calendarManager reload];\n```\nFor changing locale and timeZone in Swift use:\n\n```swift\nlet locale = Locale(identifier: \"fr_FR\")\nlet timeZone = TimeZone.init(abbreviation: \"CDT\")\ncalendarManager = JTCalendarManager(locale: locale, andTimeZone: timeZone)\n```\n\n### Date comparaison\n\nBe careful when you compare two different dates, you have to take care of the time zone.\nAn helper is provided for some basic operations:\n\n```objective-c\n[_calendarManager.dateHelper date:dateA isTheSameMonthThan:dateB];\n[_calendarManager.dateHelper date:dateA isTheSameWeekThan:dateB];\n[_calendarManager.dateHelper date:dateA isTheSameDayThan:dateB];\n\n// Use to limit the calendar range\n[_calendarManager.dateHelper date:date isEqualOrAfter:minDate andEqualOrBefore:maxDate];\n\n```\n\n### Optimization\n\nEvery 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.\n\nIf you have to fetch some data from something slow, I recommend to create a cache and query this cache in `prepareDayView` method.\nYou 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).\n\n## Questions\n\nBefore asking any questions be sure to explore the Example project.\nCheck also [JTCalendarDelegate](JTCalendar/JTCalendarDelegate.h) and [JTCalendarSettings](JTCalendar/JTCalendarSettings.h) files.\n\nDon't use `NSLog` to print date use a `NSDateFormatter`, `NSLog`doesn't take care of the timezone.\n\n```objective-c\nNSDateFormatter *dateFormatter = [_calendarManager.dateHelper createDateFormatter];\ndateFormatter.dateFormat = @\"yyyy'-'MM'-'dd' 'HH':'mm':'ss\";\nNSLog(@\"%@\", [dateFormatter stringFromDate:yourDate]);\n```\n\n## Requirements\n\n- iOS 7 or higher\n- Automatic Reference Counting (ARC)\n\n## Author\n\n- [Jonathan VUKOVICH TRIBOUHARET](https://github.com/jonathantribouharet) ([@johnvuko](https://twitter.com/johnvuko))\n\n## License\n\nJTCalendar is released under the MIT license. See the LICENSE file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnvuko%2Fjtcalendar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnvuko%2Fjtcalendar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnvuko%2Fjtcalendar/lists"}