Just My Life & My Work

[iOS] 日曆套件 JTCalendar

選擇日期這個功能很常見,只要牽涉到日期時間都會用到,短時間的選擇(如一年、一個月、一星期等)可以使用內建Date Picker,長時間橫跨好幾年的就要考慮使用日曆來挑選日期。在這裡我來推薦我最常用的日曆套件 JTCalendar

[iOS] 日曆套件 JTCalendar.PNG

它功能算是相當強大,日曆可以垂直水平翻前翻後,想客製化顏色、大小等特性皆可。

看官方操作動畫圖:

[iOS] 日曆套件 JTCalendar3.gif

我特愛用CocoaPods

pod ‘JTCalendar’, ‘~> 2.0’

我介面是這麼設計:

[iOS] 日曆套件 JTCalendar2.png

程式碼很簡單這麼寫:

/**
 Theme: Open Source JTCalendar
 IDE: Xcode 9
 Language: Objective C
 Date: 107/06/21
 Author: HappyMan
 Blog: https://cg2010studio.com/
 */

// TPFileViewController.h
#import 

@interface TPFileViewController : UIViewController
{

}

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

// TPFileViewController.m
@interface TPFileViewController ()
{
    NSMutableDictionary *_eventsByDate;

    NSDate *_todayDate;
    NSDate *_minDate;
    NSDate *_maxDate;

    NSDate *_dateSelected;
}

@end

@implementation TPFileViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    _calendarManager = [JTCalendarManager new];
    _calendarManager.delegate = self;

    [_calendarManager setMenuView:_calendarMenuView];
    [_calendarManager setContentView:_calendarContentView];
    [_calendarManager setDate:[NSDate date]];

    [self createRandomEvents];
}

#pragma mark - JTCalendarDelegate
- (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;
    }
}

- (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];
        }
    }
}

// Used only to have a key for _eventsByDate
- (NSDateFormatter *)dateFormatter
{
    NSDateFormatter *dateFormatter;
    if(!dateFormatter){
        dateFormatter = [NSDateFormatter new];
        dateFormatter.dateFormat = @"YYYY/MM/dd";
    }

    return dateFormatter;
}

- (BOOL)haveEventForDay:(NSDate *)date
{
    NSString *key = [[self dateFormatter] stringFromDate:date];

    if(_eventsByDate[key] && [_eventsByDate[key] count] > 0){
        return YES;
    }

    return NO;

}

// 產生任意事件
- (void)createRandomEvents
{
    _eventsByDate = [NSMutableDictionary new];

    for(int i = 0; i <span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>&lt; 30; ++i){
        // Generate 30 random dates between now and 60 days later
        NSDate *randomDate = [NSDate dateWithTimeInterval:(rand() % (3600 * 24 * 60)) sinceDate:[NSDate date]];

        // Use the date as key for eventsByDate
        NSString *key = [[self dateFormatter] stringFromDate:randomDate];

        if(!_eventsByDate[key]){
            _eventsByDate[key] = [NSMutableArray new];
        }

        [_eventsByDate[key] addObject:randomDate];
    }
}

@end

接下來就根據實際應用來呈現點擊之後的行為囉!

參考:

隨意留個言吧:)~

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料

標籤雲