Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/johnvuko/JTCalendar
A customizable calendar view for iOS.
https://github.com/johnvuko/JTCalendar
calendar ios
Last synced: 3 months ago
JSON representation
A customizable calendar view for iOS.
- Host: GitHub
- URL: https://github.com/johnvuko/JTCalendar
- Owner: johnvuko
- License: mit
- Created: 2014-10-29T18:39:06.000Z (about 10 years ago)
- Default Branch: master
- Last Pushed: 2021-12-06T16:23:29.000Z (almost 3 years ago)
- Last Synced: 2024-07-22T10:48:16.519Z (3 months ago)
- Topics: calendar, ios
- Language: Objective-C
- Homepage:
- Size: 764 KB
- Stars: 2,763
- Watchers: 94
- Forks: 531
- Open Issues: 118
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-ios - JTCalendar - A customizable calendar view for iOS. (UI / Calendar)
- awesome-cocoa - JTCalendar
- awesome-ios-star - JTCalendar - A customizable calendar view for iOS. (UI / Calendar)
README
# JTCalendar
[![CI Status](http://img.shields.io/travis/jonathantribouharet/JTCalendar.svg)](https://travis-ci.org/jonathantribouharet/JTCalendar)
![Version](https://img.shields.io/cocoapods/v/JTCalendar.svg)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
![License](https://img.shields.io/cocoapods/l/JTCalendar.svg)
![Platform](https://img.shields.io/cocoapods/p/JTCalendar.svg)JTCalendar is an easily customizable calendar control for iOS.
## Installation
With [CocoaPods](http://cocoapods.org), add this line to your Podfile.
pod 'JTCalendar', '~> 2.0'
### Carthage
To use this project with [Carthage](https://github.com/Carthage/Carthage), add this line to your Cartfile.
github "jonathantribouharet/JTCalendar" ~> 2.2
## Screenshots
![Example](./Screens/example.gif "Example View")
![Example](./Screens/example.png "Example View")### 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.
```objective-c
#import#import
@interface ViewController : UIViewController
@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.
```objective-c
@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];`.```objective-c
- (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.
```objective-c
- (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.
```objective-c
_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](JTCalendar/JTCalendarDelegate.h) file and the Example project.
For example:
```objective-c
// 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 *)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.```objective-c
// 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.
```objective-c
- (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:
```objective-c
_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:```swift
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:```objective-c
[_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](JTCalendar/JTCalendarDelegate.h) and [JTCalendarSettings](JTCalendar/JTCalendarSettings.h) files.Don't use `NSLog` to print date use a `NSDateFormatter`, `NSLog`doesn't take care of the timezone.
```objective-c
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
- [Jonathan VUKOVICH TRIBOUHARET](https://github.com/jonathantribouharet) ([@johnvuko](https://twitter.com/johnvuko))
## License
JTCalendar is released under the MIT license. See the LICENSE file for more info.