diff --git a/Example/FullScreenExampleViewController.m b/Example/FullScreenExampleViewController.m index 8ed70c4..b42170d 100644 --- a/Example/FullScreenExampleViewController.m +++ b/Example/FullScreenExampleViewController.m @@ -28,7 +28,7 @@ view.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1.0]; self.view = view; - FSCalendar *calendar = [[FSCalendar alloc] initWithFrame:CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.height)]; + FSCalendar *calendar = [[FSCalendar alloc] initWithFrame:CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.height-64)]; calendar.dataSource = self; calendar.delegate = self; calendar.pagingEnabled = NO; // important @@ -61,9 +61,21 @@ - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; - _calendar.frame = CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.height); + _calendar.frame = CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.height-64); } +/* +- (NSDate *)minimumDateForCalendar:(FSCalendar *)calendar +{ + return [NSDate date]; +} + +- (NSDate *)maximumDateForCalendar:(FSCalendar *)calendar +{ + return [[NSDate date] fs_dateByAddingMonths:3]; +} +*/ + - (void)calendar:(FSCalendar *)calendar didSelectDate:(NSDate *)date { NSLog(@"did select %@",[date fs_stringWithFormat:@"yyyy/MM/dd"]); diff --git a/Example/StoryboardExampleViewController.m b/Example/StoryboardExampleViewController.m index e14ae9d..6ddedb1 100644 --- a/Example/StoryboardExampleViewController.m +++ b/Example/StoryboardExampleViewController.m @@ -72,15 +72,15 @@ // return date.fs_day % 5 == 0; //} -//- (NSDate *)minimumDateForCalendar:(FSCalendar *)calendar -//{ -// return [NSDate fs_dateWithYear:2015 month:6 day:15]; -//} -// -//- (NSDate *)maximumDateForCalendar:(FSCalendar *)calendar -//{ -// return [NSDate fs_dateWithYear:2025 month:7 day:15]; -//} +- (NSDate *)minimumDateForCalendar:(FSCalendar *)calendar +{ + return [NSDate date]; +} + +- (NSDate *)maximumDateForCalendar:(FSCalendar *)calendar +{ + return [[NSDate date] fs_dateByAddingMonths:3]; +} - (void)calendar:(FSCalendar *)calendar didDeselectDate:(NSDate *)date diff --git a/FSCalendar/FSCalendar.m b/FSCalendar/FSCalendar.m index d3b781f..0de3ef0 100644 --- a/FSCalendar/FSCalendar.m +++ b/FSCalendar/FSCalendar.m @@ -474,7 +474,7 @@ if (cell.dateIsPlaceholder) { if ([self isDateInRange:cell.date]) { [self selectDate:cell.date scrollToDate:YES forPlaceholder:YES]; - } else if (![cell.date fs_isEqualToDateForMonth:_currentPage]) { + } else if (![cell.date fs_isEqualToDateForMonth:_currentPage]){ [self scrollToPageForDate:cell.date animated:YES]; } return NO; @@ -650,7 +650,7 @@ _needsAdjustingMonthPosition = YES; _needsAdjustingTextSize = YES; [_collectionViewLayout invalidateLayout]; // Necessary in Swift. Anyone can tell why? - + [_stickyHeaderMapTable.dictionaryRepresentation.allValues setValue:@YES forKey:@"needsAdjustingFrames"]; _preferedWeekdayHeight = FSCalendarAutomaticDimension; _preferedRowHeight = FSCalendarAutomaticDimension; _preferedHeaderHeight = FSCalendarAutomaticDimension; @@ -879,7 +879,7 @@ - (NSArray *)selectedDates { - return _selectedDates; + return [NSArray arrayWithArray:_selectedDates]; } - (CGFloat)preferedHeaderHeight @@ -1187,7 +1187,7 @@ [NSException raise:@"selectedDate out of range" format:@""]; } NSDate *targetDate = [date fs_daysFrom:_minimumDate] < 0 ? _minimumDate.copy : date; - targetDate = [targetDate fs_daysFrom:_maximumDate] > 0 ? _maximumDate.copy : date; + targetDate = [targetDate fs_daysFrom:_maximumDate] > 0 ? _maximumDate.copy : targetDate; targetDate = targetDate.fs_dateByIgnoringTimeComponents; NSIndexPath *targetIndexPath = [self indexPathForDate:targetDate]; @@ -1261,7 +1261,7 @@ _supressEvent = !animated; NSDate * targetDate = [date fs_daysFrom:_minimumDate] < 0 ? _minimumDate : date; - targetDate = [targetDate fs_daysFrom:_maximumDate] > 0 ? _maximumDate : date; + targetDate = [targetDate fs_daysFrom:_maximumDate] > 0 ? _maximumDate : targetDate; NSInteger scrollOffset = 0; switch (_scope) { case FSCalendarScopeMonth: { @@ -1301,7 +1301,8 @@ [self setNeedsLayout]; } else { CGRect headerFrame = [_collectionViewLayout layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:scrollOffset]].frame; - [_collectionView setContentOffset:headerFrame.origin animated:animated]; + CGPoint targetOffset = CGPointMake(0, MIN(headerFrame.origin.y,_collectionView.contentSize.height-_collectionView.fs_bottom)); + [_collectionView setContentOffset:targetOffset animated:animated]; } } @@ -1347,9 +1348,7 @@ switch (_scope) { case FSCalendarScopeMonth: { NSDate *currentPage = [_minimumDate.fs_firstDayOfMonth fs_dateByAddingMonths:indexPath.section]; - NSDate *firstDayOfMonth = [NSDate fs_dateWithYear:currentPage.fs_year - month:currentPage.fs_month - day:1]; + NSDate *firstDayOfMonth = currentPage.fs_firstDayOfMonth; NSInteger numberOfPlaceholdersForPrev = ((firstDayOfMonth.fs_weekday - _firstWeekday) + 7) % 7 ?: (7 * !self.floatingMode); NSDate *firstDateOfPage = [firstDayOfMonth fs_dateBySubtractingDays:numberOfPlaceholdersForPrev]; switch (_collectionViewLayout.scrollDirection) { @@ -1531,87 +1530,79 @@ - (void)invalidateAppearanceForCell:(FSCalendarCell *)cell { - void(^configure)() = ^{ - - cell.preferedSelectionColor = [self preferedSelectionColorForDate:cell.date]; - cell.preferedTitleDefaultColor = [self preferedTitleDefaultColorForDate:cell.date]; - cell.preferedTitleSelectionColor = [self preferedTitleSelectionColorForDate:cell.date]; - if (cell.subtitle) { - cell.preferedSubtitleDefaultColor = [self preferedSubtitleDefaultColorForDate:cell.date]; - cell.preferedSubtitleSelectionColor = [self preferedSubtitleSelectionColorForDate:cell.date]; - } - if (cell.hasEvent) cell.preferedEventColor = [self preferedEventColorForDate:cell.date]; - cell.preferedBorderDefaultColor = [self preferedBorderDefaultColorForDate:cell.date]; - cell.preferedBorderSelectionColor = [self preferedBorderSelectionColorForDate:cell.date]; +#define m_async_background1 \ +\ + cell.preferedSelectionColor = [self preferedSelectionColorForDate:cell.date]; \ + cell.preferedTitleDefaultColor = [self preferedTitleDefaultColorForDate:cell.date]; \ + cell.preferedTitleSelectionColor = [self preferedTitleSelectionColorForDate:cell.date]; \ + if (cell.subtitle) { \ + cell.preferedSubtitleDefaultColor = [self preferedSubtitleDefaultColorForDate:cell.date]; \ + cell.preferedSubtitleSelectionColor = [self preferedSubtitleSelectionColorForDate:cell.date]; \ + } \ + if (cell.hasEvent) cell.preferedEventColor = [self preferedEventColorForDate:cell.date]; \ + cell.preferedBorderDefaultColor = [self preferedBorderDefaultColorForDate:cell.date]; \ + cell.preferedBorderSelectionColor = [self preferedBorderSelectionColorForDate:cell.date]; \ cell.preferedCellShape = [self preferedCellShapeForDate:cell.date]; - - }; - if (_asyncronous) { + + if (_asyncronous && !self.ibEditing) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - configure(); + m_async_background1 dispatch_async(dispatch_get_main_queue(), ^{ [cell setNeedsLayout]; }); }); } else { - configure(); + m_async_background1 [cell setNeedsLayout]; } } - (void)reloadDataForCell:(FSCalendarCell *)cell atIndexPath:(NSIndexPath *)indexPath { - void(^configure)() = ^{ - - cell.calendar = self; - cell.appearance = _appearance; - cell.date = [self dateForIndexPath:indexPath]; - cell.image = [self imageForDate:cell.date]; - cell.subtitle = [self subtitleForDate:cell.date]; - cell.hasEvent = [self hasEventForDate:cell.date]; - cell.dateIsSelected = [self.selectedDates containsObject:cell.date]; - cell.dateIsToday = [cell.date fs_isEqualToDateForDay:_today]; - - switch (_scope) { - case FSCalendarScopeMonth: { - NSDate *month = [_minimumDate.fs_firstDayOfMonth fs_dateByAddingMonths:indexPath.section].fs_dateByIgnoringTimeComponents; - cell.dateIsPlaceholder = ![cell.date fs_isEqualToDateForMonth:month] || ![self isDateInRange:cell.date]; - if (cell.dateIsPlaceholder) { - cell.dateIsSelected &= _pagingEnabled; - cell.dateIsToday &= _pagingEnabled; - } - break; - } - case FSCalendarScopeWeek: { - if (_pagingEnabled) { - cell.dateIsPlaceholder = ![self isDateInRange:cell.date]; - } - break; - } - default: { - break; - } + cell.calendar = self; + cell.appearance = _appearance; + cell.date = [self dateForIndexPath:indexPath]; +#define m_async_background2 \ +\ + cell.image = [self imageForDate:cell.date]; \ + cell.subtitle = [self subtitleForDate:cell.date]; \ + cell.hasEvent = [self hasEventForDate:cell.date]; \ + cell.dateIsSelected = [self.selectedDates containsObject:cell.date]; \ + cell.dateIsToday = [cell.date fs_isEqualToDateForDay:_today]; \ +\ + switch (_scope) { \ + case FSCalendarScopeMonth: { \ + NSDate *month = [_minimumDate.fs_firstDayOfMonth fs_dateByAddingMonths:indexPath.section].fs_dateByIgnoringTimeComponents; \ + cell.dateIsPlaceholder = ![cell.date fs_isEqualToDateForMonth:month] || ![self isDateInRange:cell.date]; \ + if (cell.dateIsPlaceholder) { \ + cell.dateIsSelected &= _pagingEnabled; \ + cell.dateIsToday &= _pagingEnabled; \ + } \ + break; \ + } \ + case FSCalendarScopeWeek: { \ + if (_pagingEnabled) { \ + cell.dateIsPlaceholder = ![self isDateInRange:cell.date]; \ + } \ + break; \ + } \ } - - }; - void(^layout)() = ^{ - - [self invalidateAppearanceForCell:cell]; - cell.selected = (cell.dateIsSelected && !cell.dateIsPlaceholder); +#define m_async_main2 \ + [self invalidateAppearanceForCell:cell]; \ + cell.selected = (cell.dateIsSelected && !cell.dateIsPlaceholder); \ [cell setNeedsLayout]; - }; - if (_asyncronous) { + if (_asyncronous && !self.ibEditing) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - configure(); + m_async_background2 dispatch_async(dispatch_get_main_queue(), ^{ - layout(); + m_async_main2 }); }); } else { - configure(); - layout(); + m_async_background2 + m_async_main2 } } @@ -1665,9 +1656,6 @@ if (![_selectedDates containsObject:date]) { [_selectedDates addObject:date]; } - [_selectedDates sortUsingComparator:^NSComparisonResult(NSDate *d1, NSDate *d2) { - return [d1 compare:d2] == NSOrderedDescending; - }]; } - (NSArray *)visibleStickyHeaders diff --git a/FSCalendar/FSCalendarCollectionView.m b/FSCalendar/FSCalendarCollectionView.m index 9a9aa09..7d79462 100644 --- a/FSCalendar/FSCalendarCollectionView.m +++ b/FSCalendar/FSCalendarCollectionView.m @@ -12,12 +12,22 @@ @synthesize scrollsToTop = _scrollsToTop, contentInset = _contentInset; +- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout +{ + self = [super initWithFrame:frame collectionViewLayout:layout]; + if (self) { + self.scrollsToTop = NO; + self.contentInset = UIEdgeInsetsZero; + } + return self; +} + - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { - _scrollsToTop = NO; - _contentInset = UIEdgeInsetsZero; + self.scrollsToTop = NO; + self.contentInset = UIEdgeInsetsZero; } return self; } diff --git a/README.md b/README.md index f28e56a..a098888 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ ![fscalendar](https://cloud.githubusercontent.com/assets/5186464/10262249/4fabae40-69f2-11e5-97ab-afbacd0a3da2.jpg) ## iPad -![fscalendar-ipad](https://cloud.githubusercontent.com/assets/5186464/10878242/5d087f44-8187-11e5-8c24-29bac5024a95.jpg) +![fscalendar-ipad](https://cloud.githubusercontent.com/assets/5186464/10927681/d2448cb6-82dc-11e5-9d11-f664a06698a7.jpg) # Installation diff --git a/SwiftExample/SwiftExample/Objc-Bridge-Header.h b/SwiftExample/SwiftExample/Objc-Bridge-Header.h index 41c1de3..da58d17 100644 --- a/SwiftExample/SwiftExample/Objc-Bridge-Header.h +++ b/SwiftExample/SwiftExample/Objc-Bridge-Header.h @@ -11,5 +11,6 @@ #import "FSCalendar.h" #import "NSDate+FSExtension.h" +#import "NSString+FSExtension.h" #endif diff --git a/SwiftExample/SwiftExample/ViewController.swift b/SwiftExample/SwiftExample/ViewController.swift index 001d9dc..096f5b9 100644 --- a/SwiftExample/SwiftExample/ViewController.swift +++ b/SwiftExample/SwiftExample/ViewController.swift @@ -15,14 +15,33 @@ class ViewController: UIViewController, FSCalendarDataSource, FSCalendarDelegate override func viewDidLoad() { super.viewDidLoad() - calendar.selectDate(NSDate()) calendar.scrollDirection = .Vertical -// calendar.scope = .Month -// calendar.allowsMultipleSelection = true calendar.appearance.caseOptions = [.HeaderUsesUpperCase,.WeekdayUsesUpperCase] - } + + calendar.selectDate(NSDate()) + + /* + calendar.allowsMultipleSelection = true + var dateArray = ["20160101", "20151115", "20151211", "20151201", "20151107", "20160105"] + for (var i = 0 ; i < dateArray.count; i++) { + let dateString = dateArray[i] as NSString + let date = dateString.fs_dateWithFormat("yyyyMMdd"); + calendar.selectDate(date) + } + */ + } + /* + func minimumDateForCalendar(calendar: FSCalendar!) -> NSDate! { + return NSDate().fs_firstDayOfMonth + } + + func maximumDateForCalendar(calendar: FSCalendar!) -> NSDate! { + return NSDate().fs_dateByAddingMonths(3).fs_lastDayOfMonth + } + */ + func calendar(calendar: FSCalendar!, hasEventForDate date: NSDate!) -> Bool { return date.fs_day == 5 }