From f1b828c191042d7c69d2f3f9a2ef0d4da3e2eb4c Mon Sep 17 00:00:00 2001 From: WenchaoD Date: Thu, 5 Jan 2017 15:28:19 +0800 Subject: [PATCH] Remove scope injection --- .../FSCalendar.xcodeproj/project.pbxproj | 20 ++--- .../FSCalendarScopeExampleViewController.m | 22 ++++- FSCalendar/FSCalendar.m | 84 +++++++++---------- FSCalendar/FSCalendarCalculator.m | 17 ++-- FSCalendar/FSCalendarCell.m | 2 +- FSCalendar/FSCalendarCollectionViewLayout.m | 8 +- FSCalendar/FSCalendarDynamicHeader.h | 4 +- FSCalendar/FSCalendarHeaderView.m | 4 +- FSCalendar/FSCalendarScopeHandle.m | 6 +- ...or.h => FSCalendarTransitionCoordinator.h} | 6 +- ...or.m => FSCalendarTransitionCoordinator.m} | 53 ++++++------ 11 files changed, 114 insertions(+), 112 deletions(-) rename FSCalendar/{FSCalendarAnimator.h => FSCalendarTransitionCoordinator.h} (90%) rename FSCalendar/{FSCalendarAnimator.m => FSCalendarTransitionCoordinator.m} (96%) diff --git a/Example-Objc/FSCalendar.xcodeproj/project.pbxproj b/Example-Objc/FSCalendar.xcodeproj/project.pbxproj index 4429a33..a6c0c2a 100644 --- a/Example-Objc/FSCalendar.xcodeproj/project.pbxproj +++ b/Example-Objc/FSCalendar.xcodeproj/project.pbxproj @@ -49,9 +49,9 @@ 30B0BB021B8D9B6C004B9476 /* FSCalendarCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 30B0BAC31B8D8E22004B9476 /* FSCalendarCell.h */; settings = {ATTRIBUTES = (Public, ); }; }; 30B0BB031B8D9B6D004B9476 /* FSCalendarDynamicHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 30B0BAC51B8D8E22004B9476 /* FSCalendarDynamicHeader.h */; settings = {ATTRIBUTES = (Private, ); }; }; 30B0BB041B8D9B6D004B9476 /* FSCalendarHeaderView.h in Headers */ = {isa = PBXBuildFile; fileRef = 30B0BAC61B8D8E22004B9476 /* FSCalendarHeaderView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 30CEF9001C950C1F008EAFB1 /* FSCalendarAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = 30CEF8FE1C950C1F008EAFB1 /* FSCalendarAnimator.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 30CEF9011C950C1F008EAFB1 /* FSCalendarAnimator.m in Sources */ = {isa = PBXBuildFile; fileRef = 30CEF8FF1C950C1F008EAFB1 /* FSCalendarAnimator.m */; }; - 30CEF9021C950C1F008EAFB1 /* FSCalendarAnimator.m in Sources */ = {isa = PBXBuildFile; fileRef = 30CEF8FF1C950C1F008EAFB1 /* FSCalendarAnimator.m */; }; + 30CEF9001C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 30CEF8FE1C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 30CEF9011C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.m in Sources */ = {isa = PBXBuildFile; fileRef = 30CEF8FF1C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.m */; }; + 30CEF9021C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.m in Sources */ = {isa = PBXBuildFile; fileRef = 30CEF8FF1C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.m */; }; 30D55B101C90240000BB43D5 /* HidePlaceholderViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 30D55B0F1C90240000BB43D5 /* HidePlaceholderViewController.m */; }; 30DBE3C41DC641AD005A22B7 /* FSCalendarCalculator.h in Headers */ = {isa = PBXBuildFile; fileRef = 30DBE3C21DC641AD005A22B7 /* FSCalendarCalculator.h */; settings = {ATTRIBUTES = (Private, ); }; }; 30DBE3C51DC641AD005A22B7 /* FSCalendarCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = 30DBE3C31DC641AD005A22B7 /* FSCalendarCalculator.m */; }; @@ -145,8 +145,8 @@ 30B0BAC61B8D8E22004B9476 /* FSCalendarHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSCalendarHeaderView.h; sourceTree = ""; }; 30B0BAC71B8D8E22004B9476 /* FSCalendarHeaderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSCalendarHeaderView.m; sourceTree = ""; }; 30B0BACA1B8D8E22004B9476 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 30CEF8FE1C950C1F008EAFB1 /* FSCalendarAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSCalendarAnimator.h; sourceTree = ""; }; - 30CEF8FF1C950C1F008EAFB1 /* FSCalendarAnimator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSCalendarAnimator.m; sourceTree = ""; }; + 30CEF8FE1C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSCalendarTransitionCoordinator.h; sourceTree = ""; }; + 30CEF8FF1C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSCalendarTransitionCoordinator.m; sourceTree = ""; }; 30D55B0E1C90240000BB43D5 /* HidePlaceholderViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HidePlaceholderViewController.h; sourceTree = SOURCE_ROOT; }; 30D55B0F1C90240000BB43D5 /* HidePlaceholderViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HidePlaceholderViewController.m; sourceTree = SOURCE_ROOT; }; 30DBE3C21DC641AD005A22B7 /* FSCalendarCalculator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSCalendarCalculator.h; sourceTree = ""; }; @@ -258,8 +258,8 @@ 30A495531DCAD9E6000B2F31 /* FSCalendarWeekdayView.m */, 30FCB3941BAAD112002B87AD /* FSCalendarStickyHeader.h */, 30FCB3951BAAD112002B87AD /* FSCalendarStickyHeader.m */, - 30CEF8FE1C950C1F008EAFB1 /* FSCalendarAnimator.h */, - 30CEF8FF1C950C1F008EAFB1 /* FSCalendarAnimator.m */, + 30CEF8FE1C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.h */, + 30CEF8FF1C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.m */, 301F79C91DFD39E700D8631E /* FSCalendarDelegationProxy.h */, 301F79CA1DFD39E700D8631E /* FSCalendarDelegationProxy.m */, 30F4C90D1E07C12B00D2EC4D /* FSCalendarDelegationFactory.h */, @@ -422,7 +422,7 @@ 301F79CB1DFD39E700D8631E /* FSCalendarDelegationProxy.h in Headers */, 30F4C90F1E07C12B00D2EC4D /* FSCalendarDelegationFactory.h in Headers */, 30DBE3C41DC641AD005A22B7 /* FSCalendarCalculator.h in Headers */, - 30CEF9001C950C1F008EAFB1 /* FSCalendarAnimator.h in Headers */, + 30CEF9001C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.h in Headers */, 30B0BB031B8D9B6D004B9476 /* FSCalendarDynamicHeader.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -593,7 +593,7 @@ 3065CA971CD31B81006C218D /* FSCalendarScopeHandle.m in Sources */, 308B58D81CC08FFA004E812D /* ButtonsViewController.m in Sources */, 30B0BAD11B8D8E23004B9476 /* FSCalendarAppearance.m in Sources */, - 30CEF9011C950C1F008EAFB1 /* FSCalendarAnimator.m in Sources */, + 30CEF9011C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.m in Sources */, EEC9C03A1BDC9E7000383A07 /* FSCalendarCollectionView.m in Sources */, 301F79CC1DFD39E700D8631E /* FSCalendarDelegationProxy.m in Sources */, 30D55B101C90240000BB43D5 /* HidePlaceholderViewController.m in Sources */, @@ -623,7 +623,7 @@ 3055B1C41DA9323A002AFA13 /* FSCalendarExtensions.m in Sources */, 309539911C38D66C00BD37AA /* FSCalendarCollectionViewLayout.m in Sources */, 3065CA981CD31B81006C218D /* FSCalendarScopeHandle.m in Sources */, - 30CEF9021C950C1F008EAFB1 /* FSCalendarAnimator.m in Sources */, + 30CEF9021C950C1F008EAFB1 /* FSCalendarTransitionCoordinator.m in Sources */, 30FCB3981BAAD112002B87AD /* FSCalendarStickyHeader.m in Sources */, 30F4C9111E07C12B00D2EC4D /* FSCalendarDelegationFactory.m in Sources */, ); diff --git a/Example-Objc/FSCalendarScopeExampleViewController.m b/Example-Objc/FSCalendarScopeExampleViewController.m index 9e929a4..0cdbb0a 100644 --- a/Example-Objc/FSCalendarScopeExampleViewController.m +++ b/Example-Objc/FSCalendarScopeExampleViewController.m @@ -8,6 +8,8 @@ #import "FSCalendarScopeExampleViewController.h" +static void * __KVOContext; + @implementation FSCalendarScopeExampleViewController #pragma mark - Life cycle @@ -28,18 +30,32 @@ [self.view addGestureRecognizer:panGesture]; self.scopeGesture = panGesture; - // While the scope gesture begin, the tableView gesture cancel. + // While the scope gesture begin, the pan gesture of tableView should cancel. [self.tableView.panGestureRecognizer requireGestureRecognizerToFail:panGesture]; + self.calendar.scope = FSCalendarScopeWeek; - // Uncomment this to perform an 'initial-week-scope' - _calendar.scope = FSCalendarScopeWeek; + [self.calendar addObserver:self forKeyPath:@"scope" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:__KVOContext]; } - (void)dealloc { + [self.calendar removeObserver:self forKeyPath:@"scope" context:__KVOContext]; NSLog(@"%s",__FUNCTION__); } +#pragma mark - KVO + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (context == __KVOContext) { + FSCalendarScope oldScope = [change[NSKeyValueChangeOldKey] unsignedIntegerValue]; + FSCalendarScope newScope = [change[NSKeyValueChangeNewKey] unsignedIntegerValue]; + NSLog(@"From %@ to %@",(oldScope==FSCalendarScopeWeek?@"week":@"month"),(newScope==FSCalendarScopeWeek?@"week":@"month")); + } else { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + #pragma mark - UIGestureRecognizerDelegate // Whether scope gesture should begin diff --git a/FSCalendar/FSCalendar.m b/FSCalendar/FSCalendar.m index 44b2c5f..9503303 100644 --- a/FSCalendar/FSCalendar.m +++ b/FSCalendar/FSCalendar.m @@ -17,7 +17,7 @@ #import "FSCalendarDynamicHeader.h" #import "FSCalendarCollectionView.h" -#import "FSCalendarAnimator.h" +#import "FSCalendarTransitionCoordinator.h" #import "FSCalendarCalculator.h" #import "FSCalendarDelegationFactory.h" @@ -77,7 +77,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { @property (weak , nonatomic) FSCalendarCollectionView *collectionView; @property (weak , nonatomic) FSCalendarCollectionViewLayout *collectionViewLayout; -@property (strong, nonatomic) FSCalendarAnimator *animator; +@property (strong, nonatomic) FSCalendarTransitionCoordinator *transitionCoordinator; @property (strong, nonatomic) FSCalendarCalculator *calculator; @property (weak , nonatomic) FSCalendarHeaderTouchDeliver *deliver; @@ -265,7 +265,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { [self registerMainRunloopObserver]; // Assistants - self.animator = [[FSCalendarAnimator alloc] initWithCalendar:self]; + self.transitionCoordinator = [[FSCalendarTransitionCoordinator alloc] initWithCalendar:self]; self.calculator = [[FSCalendarCalculator alloc] initWithCalendar:self]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil]; @@ -289,7 +289,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { - (void)setBounds:(CGRect)bounds { [super setBounds:bounds]; - if (!CGRectIsEmpty(bounds) && self.animator.state == FSCalendarTransitionStateIdle) { + if (!CGRectIsEmpty(bounds) && self.transitionCoordinator.state == FSCalendarTransitionStateIdle) { [self invalidateViewFrames]; } } @@ -297,7 +297,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { - (void)setFrame:(CGRect)frame { [super setFrame:frame]; - if (!CGRectIsEmpty(frame) && self.animator.state == FSCalendarTransitionStateIdle) { + if (!CGRectIsEmpty(frame) && self.transitionCoordinator.state == FSCalendarTransitionStateIdle) { [self invalidateViewFrames]; } } @@ -332,8 +332,8 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { if (_needsAdjustingViewFrame) { _needsAdjustingViewFrame = NO; - if (CGSizeEqualToSize(_animator.cachedMonthSize, CGSizeZero)) { - _animator.cachedMonthSize = self.frame.size; + if (CGSizeEqualToSize(_transitionCoordinator.cachedMonthSize, CGSizeZero)) { + _transitionCoordinator.cachedMonthSize = self.frame.size; } BOOL needsAdjustingBoundingRect = (self.scope == FSCalendarScopeMonth) && @@ -341,15 +341,13 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { !self.hasValidateVisibleLayout; if (_scopeHandle) { - CGFloat scopeHandleHeight = self.animator.cachedMonthSize.height*0.08; + CGFloat scopeHandleHeight = self.transitionCoordinator.cachedMonthSize.height*0.08; _contentView.frame = CGRectMake(0, 0, self.fs_width, self.fs_height-scopeHandleHeight); _scopeHandle.frame = CGRectMake(0, _contentView.fs_bottom, self.fs_width, scopeHandleHeight); } else { _contentView.frame = self.bounds; } - if (_needsLayoutForWeekMode) _scope = FSCalendarScopeMonth; - CGFloat headerHeight = self.preferredHeaderHeight; CGFloat weekdayHeight = self.preferredWeekdayHeight; CGFloat rowHeight = self.preferredRowHeight; @@ -358,25 +356,23 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { rowHeight = FSCalendarFloor(rowHeight*2)*0.5; // Round to nearest multiple of 0.5. e.g. (16.8->16.5),(16.2->16.0) } - if (_needsLayoutForWeekMode) _scope = FSCalendarScopeWeek; - self.calendarHeaderView.frame = CGRectMake(0, 0, self.fs_width, headerHeight); self.calendarWeekdayView.frame = CGRectMake(0, self.calendarHeaderView.fs_bottom, self.contentView.fs_width, weekdayHeight); _deliver.frame = CGRectMake(self.calendarHeaderView.fs_left, self.calendarHeaderView.fs_top, self.calendarHeaderView.fs_width, headerHeight+weekdayHeight); _deliver.hidden = self.calendarHeaderView.hidden; if (!self.floatingMode) { - switch (_scope) { + switch (self.transitionCoordinator.representingScope) { case FSCalendarScopeMonth: { CGFloat contentHeight = rowHeight*6 + padding*2; CGFloat currentHeight = rowHeight*[self.calculator numberOfRowsInMonth:self.currentPage] + padding*2; _daysContainer.frame = CGRectMake(0, headerHeight+weekdayHeight, self.fs_width, currentHeight); _collectionView.frame = CGRectMake(0, 0, _daysContainer.fs_width, contentHeight); if (needsAdjustingBoundingRect) { - self.animator.state = FSCalendarTransitionStateChanging; + self.transitionCoordinator.state = FSCalendarTransitionStateChanging; CGRect boundingRect = (CGRect){CGPointZero,[self sizeThatFits:self.frame.size]}; [self.delegateProxy calendar:self boundingRectWillChange:boundingRect animated:NO]; - self.animator.state = FSCalendarTransitionStateIdle; + self.transitionCoordinator.state = FSCalendarTransitionStateIdle; } break; } @@ -402,8 +398,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { if (_needsLayoutForWeekMode) { _needsLayoutForWeekMode = NO; - _scope = FSCalendarScopeWeek; - [self.animator performScopeTransitionFromScope:FSCalendarScopeMonth toScope:FSCalendarScopeWeek animated:NO]; + [self.transitionCoordinator performScopeTransitionFromScope:FSCalendarScopeMonth toScope:FSCalendarScopeWeek animated:NO]; } else { if (_needsAdjustingMonthPosition) { _needsAdjustingMonthPosition = NO; @@ -431,11 +426,11 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { - (CGSize)sizeThatFits:(CGSize)size { - switch (self.animator.transition) { + switch (self.transitionCoordinator.transition) { case FSCalendarTransitionNone: return [self sizeThatFits:size scope:_scope]; case FSCalendarTransitionWeekToMonth: - if (self.animator.state == FSCalendarTransitionStateChanging) { + if (self.transitionCoordinator.state == FSCalendarTransitionStateChanging) { return [self sizeThatFits:size scope:FSCalendarScopeMonth]; } case FSCalendarTransitionMonthToWeek: @@ -480,22 +475,18 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { - if (self.animator.transition == FSCalendarTransitionWeekToMonth && self.animator.state == FSCalendarTransitionStateChanging) { - return 42; - } - if (!self.floatingMode) { - switch (_scope) { - case FSCalendarScopeMonth: { - return 42; - } - case FSCalendarScopeWeek: { - return 7; - } - } - } else { + if (self.floatingMode) { NSInteger numberOfRows = [self.calculator numberOfRowsInSection:section]; return numberOfRows * 7; } + switch (self.transitionCoordinator.representingScope) { + case FSCalendarScopeMonth: { + return 42; + } + case FSCalendarScopeWeek: { + return 7; + } + } return 7; } @@ -699,7 +690,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { _currentPage = targetPage; [self.delegateProxy calendarCurrentPageDidChange:self]; if (_placeholderType != FSCalendarPlaceholderTypeFillSixRows) { - [self.animator performBoundingRectTransitionFromMonth:lastPage toMonth:_currentPage duration:0.25]; + [self.transitionCoordinator performBoundingRectTransitionFromMonth:lastPage toMonth:_currentPage duration:0.25]; } [self didChangeValueForKey:@"currentPage"]; } @@ -979,7 +970,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { if (_preferredWeekdayHeight == FSCalendarAutomaticDimension) { if (!self.floatingMode) { CGFloat DIYider = FSCalendarStandardMonthlyPageHeight; - CGFloat contentHeight = self.animator.cachedMonthSize.height*(1-_showsScopeHandle*0.08); + CGFloat contentHeight = self.transitionCoordinator.cachedMonthSize.height*(1-_showsScopeHandle*0.08); _preferredHeaderHeight = (FSCalendarStandardHeaderHeight/DIYider)*contentHeight; _preferredHeaderHeight -= (_preferredHeaderHeight-FSCalendarStandardHeaderHeight)*0.5; } else { @@ -997,7 +988,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { if (_preferredWeekdayHeight == FSCalendarAutomaticDimension) { if (!self.floatingMode) { CGFloat DIYider = FSCalendarStandardMonthlyPageHeight; - CGFloat contentHeight = self.animator.cachedMonthSize.height*(1-_showsScopeHandle*0.08); + CGFloat contentHeight = self.transitionCoordinator.cachedMonthSize.height*(1-_showsScopeHandle*0.08); _preferredWeekdayHeight = (FSCalendarStandardWeekdayHeight/DIYider)*contentHeight; } else { _preferredWeekdayHeight = FSCalendarStandardWeekdayHeight*MAX(1, FSCalendarDeviceIsIPad*1.5)*_lineHeightMultiplier; @@ -1013,7 +1004,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { if (_preferredRowHeight == FSCalendarAutomaticDimension) { CGFloat headerHeight = self.preferredHeaderHeight; CGFloat weekdayHeight = self.preferredWeekdayHeight; - CGFloat contentHeight = self.animator.cachedMonthSize.height-headerHeight-weekdayHeight-_scopeHandle.fs_height; + CGFloat contentHeight = self.transitionCoordinator.cachedMonthSize.height-headerHeight-weekdayHeight-_scopeHandle.fs_height; CGFloat padding = 5; if (!self.floatingMode) { _preferredRowHeight = (contentHeight-padding*2)/6.0; @@ -1023,6 +1014,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { } return _preferredRowHeight; } + - (BOOL)floatingMode { return _scope == FSCalendarScopeMonth && _scrollEnabled && !_pagingEnabled; @@ -1039,8 +1031,8 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { - (UIPanGestureRecognizer *)scopeGesture { if (!_scopeGesture) { - UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self.animator action:@selector(handleScopeGesture:)]; - panGesture.delegate = self.animator; + UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self.transitionCoordinator action:@selector(handleScopeGesture:)]; + panGesture.delegate = self.transitionCoordinator; panGesture.minimumNumberOfTouches = 1; panGesture.maximumNumberOfTouches = 2; panGesture.enabled = NO; @@ -1122,9 +1114,9 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { return; } - if (self.animator.state == FSCalendarTransitionStateIdle) { + if (self.transitionCoordinator.state == FSCalendarTransitionStateIdle) { m_set_scope - [self.animator performScopeTransitionFromScope:prevScope toScope:scope animated:animated]; + [self.transitionCoordinator performScopeTransitionFromScope:prevScope toScope:scope animated:animated]; } } @@ -1243,7 +1235,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { - (void)handleScopeGesture:(UIPanGestureRecognizer *)sender { - [self.animator handleScopeGesture:sender]; + [self.transitionCoordinator handleScopeGesture:sender]; } #pragma mark - Private methods @@ -1307,7 +1299,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { if ([self isDateInDifferentPage:date]) { [self willChangeValueForKey:@"currentPage"]; NSDate *lastPage = _currentPage; - switch (_scope) { + switch (self.transitionCoordinator.representingScope) { case FSCalendarScopeMonth: { _currentPage = [self.gregorian fs_firstDayOfMonth:date]; break; @@ -1320,8 +1312,8 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { if (!_supressEvent && self.hasValidateVisibleLayout) { _supressEvent = YES; [self.delegateProxy calendarCurrentPageDidChange:self]; - if (_placeholderType != FSCalendarPlaceholderTypeFillSixRows && self.animator.state == FSCalendarTransitionStateIdle) { - [self.animator performBoundingRectTransitionFromMonth:lastPage toMonth:_currentPage duration:0.33]; + if (_placeholderType != FSCalendarPlaceholderTypeFillSixRows && self.transitionCoordinator.state == FSCalendarTransitionStateIdle) { + [self.transitionCoordinator performBoundingRectTransitionFromMonth:lastPage toMonth:_currentPage duration:0.33]; } _supressEvent = NO; } @@ -1345,7 +1337,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { - (BOOL)isPageInRange:(NSDate *)page { BOOL flag = YES; - switch (self.scope) { + switch (self.transitionCoordinator.representingScope) { case FSCalendarScopeMonth: { NSDateComponents *c1 = [self.gregorian components:NSCalendarUnitDay fromDate:[self.gregorian fs_firstDayOfMonth:self.minimumDate] toDate:page options:0]; flag &= (c1.day>=0); @@ -1568,7 +1560,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { cell.dateIsToday = self.today?[self.gregorian isDate:date inSameDayAsDate:self.today]:NO; cell.weekend = [self.gregorian isDateInWeekend:date]; cell.monthPosition = [self.calculator monthPositionForIndexPath:indexPath]; - switch (_scope) { + switch (self.transitionCoordinator.representingScope) { case FSCalendarScopeMonth: { cell.placeholder = (cell.monthPosition == FSCalendarMonthPositionPrevious || cell.monthPosition == FSCalendarMonthPositionNext) || ![self isDateInRange:date]; if (cell.placeholder) { diff --git a/FSCalendar/FSCalendarCalculator.m b/FSCalendar/FSCalendarCalculator.m index 98be280..6dda918 100644 --- a/FSCalendar/FSCalendarCalculator.m +++ b/FSCalendar/FSCalendarCalculator.m @@ -117,15 +117,12 @@ - (NSDate *)dateForIndexPath:(NSIndexPath *)indexPath { if (!indexPath) return nil; - if (self.calendar.animator.transition == FSCalendarTransitionWeekToMonth && self.calendar.animator.state == FSCalendarTransitionStateChanging) { - return [self dateForIndexPath:indexPath scope:FSCalendarScopeMonth]; - } - return [self dateForIndexPath:indexPath scope:self.calendar.scope]; + return [self dateForIndexPath:indexPath scope:self.calendar.transitionCoordinator.representingScope]; } - (NSIndexPath *)indexPathForDate:(NSDate *)date { - return [self indexPathForDate:date atMonthPosition:FSCalendarMonthPositionCurrent scope:self.calendar.scope]; + return [self indexPathForDate:date atMonthPosition:FSCalendarMonthPositionCurrent scope:self.calendar.transitionCoordinator.representingScope]; } - (NSIndexPath *)indexPathForDate:(NSDate *)date scope:(FSCalendarScope)scope @@ -165,12 +162,12 @@ - (NSIndexPath *)indexPathForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position { - return [self indexPathForDate:date atMonthPosition:position scope:self.calendar.scope]; + return [self indexPathForDate:date atMonthPosition:position scope:self.calendar.transitionCoordinator.representingScope]; } - (NSDate *)pageForSection:(NSInteger)section { - switch (self.calendar.scope) { + switch (self.calendar.transitionCoordinator.representingScope) { case FSCalendarScopeWeek: return [self.gregorian fs_middleDayOfWeek:[self weekForSection:section]]; case FSCalendarScopeMonth: @@ -221,10 +218,10 @@ - (NSInteger)numberOfSections { - if (self.calendar.animator.transition == FSCalendarTransitionWeekToMonth) { + if (self.calendar.transitionCoordinator.transition == FSCalendarTransitionWeekToMonth) { return self.numberOfMonths; } else { - switch (self.calendar.scope) { + switch (self.calendar.transitionCoordinator.representingScope) { case FSCalendarScopeMonth: { return self.numberOfMonths; } @@ -263,7 +260,7 @@ - (NSInteger)numberOfRowsInSection:(NSInteger)section { - if (self.calendar.scope == FSCalendarScopeWeek) return 1; + if (self.calendar.transitionCoordinator.representingScope == FSCalendarScopeWeek) return 1; NSDate *month = [self monthForSection:section]; return [self numberOfRowsInMonth:month]; } diff --git a/FSCalendar/FSCalendarCell.m b/FSCalendar/FSCalendarCell.m index 152e30a..8cf13c3 100644 --- a/FSCalendar/FSCalendarCell.m +++ b/FSCalendar/FSCalendarCell.m @@ -95,7 +95,7 @@ if (self.placeholder) { if (self.calendar.placeholderType==FSCalendarPlaceholderTypeNone) { self.contentView.hidden = self.monthPosition != FSCalendarMonthPositionCurrent; - } else if (self.calendar.placeholderType == FSCalendarPlaceholderTypeFillHeadTail && self.calendar.scope == FSCalendarScopeMonth && !self.calendar.floatingMode) { + } else if (self.calendar.placeholderType == FSCalendarPlaceholderTypeFillHeadTail && self.calendar.transitionCoordinator.representingScope == FSCalendarScopeMonth && !self.calendar.floatingMode) { NSIndexPath *indexPath = [self.calendar.collectionView indexPathForCell:self]; diff --git a/FSCalendar/FSCalendarCollectionViewLayout.m b/FSCalendar/FSCalendarCollectionViewLayout.m index f85ae89..3b87381 100644 --- a/FSCalendar/FSCalendarCollectionViewLayout.m +++ b/FSCalendar/FSCalendarCollectionViewLayout.m @@ -112,7 +112,7 @@ CGFloat height = ({ CGFloat height = FSCalendarStandardRowHeight; if (!self.calendar.floatingMode) { - switch (self.calendar.scope) { + switch (self.calendar.transitionCoordinator.representingScope) { case FSCalendarScopeMonth: { height = (self.collectionView.fs_height-self.sectionInsets.top-self.sectionInsets.bottom)/6.0; break; @@ -162,7 +162,7 @@ // Calculate item heights and tops free(self.heights); self.heights = ({ - NSInteger rowCount = self.calendar.scope == FSCalendarScopeWeek ? 1 : 6; + NSInteger rowCount = self.calendar.transitionCoordinator.representingScope == FSCalendarScopeWeek ? 1 : 6; size_t rowSize = sizeof(CGFloat)*rowCount; CGFloat *heights = malloc(rowSize); if (!self.calendar.floatingMode) { @@ -182,7 +182,7 @@ }); free(self.tops); self.tops = ({ - NSInteger rowCount = self.calendar.scope == FSCalendarScopeWeek ? 1 : 6; + NSInteger rowCount = self.calendar.transitionCoordinator.representingScope == FSCalendarScopeWeek ? 1 : 6; size_t rowSize = sizeof(CGFloat)*rowCount; CGFloat *tops = malloc(rowSize); tops[0] = self.sectionInsets.top; @@ -267,7 +267,7 @@ NSInteger wholeSections = rect.size.width/self.collectionView.fs_width; NSInteger numberOfColumns = wholeSections*7; - NSInteger numberOfRows = self.calendar.scope == FSCalendarScopeMonth ? 6 : 1; + NSInteger numberOfRows = self.calendar.transitionCoordinator.representingScope == FSCalendarScopeMonth ? 6 : 1; NSInteger startSection = rect.origin.x/self.collectionView.fs_width; CGFloat widthDelta1 = FSCalendarMod(CGRectGetMinX(rect), self.collectionView.fs_width) - self.sectionInsets.left; diff --git a/FSCalendar/FSCalendarDynamicHeader.h b/FSCalendar/FSCalendarDynamicHeader.h index 9349d30..1eee92d 100644 --- a/FSCalendar/FSCalendarDynamicHeader.h +++ b/FSCalendar/FSCalendarDynamicHeader.h @@ -19,7 +19,7 @@ #import "FSCalendarCollectionViewLayout.h" #import "FSCalendarScopeHandle.h" #import "FSCalendarCalculator.h" -#import "FSCalendarAnimator.h" +#import "FSCalendarTransitionCoordinator.h" #import "FSCalendarDelegationProxy.h" @interface FSCalendar (Dynamic) @@ -27,7 +27,7 @@ @property (readonly, nonatomic) FSCalendarCollectionView *collectionView; @property (readonly, nonatomic) FSCalendarScopeHandle *scopeHandle; @property (readonly, nonatomic) FSCalendarCollectionViewLayout *collectionViewLayout; -@property (readonly, nonatomic) FSCalendarAnimator *animator; +@property (readonly, nonatomic) FSCalendarTransitionCoordinator *transitionCoordinator; @property (readonly, nonatomic) FSCalendarCalculator *calculator; @property (readonly, nonatomic) BOOL floatingMode; @property (readonly, nonatomic) NSArray *visibleStickyHeaders; diff --git a/FSCalendar/FSCalendarHeaderView.m b/FSCalendar/FSCalendarHeaderView.m index ed10ebb..d1e2ac4 100644 --- a/FSCalendar/FSCalendarHeaderView.m +++ b/FSCalendar/FSCalendarHeaderView.m @@ -97,7 +97,7 @@ - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { - switch (self.calendar.scope) { + switch (self.calendar.transitionCoordinator.representingScope) { case FSCalendarScopeMonth: { switch (_scrollDirection) { case UICollectionViewScrollDirectionVertical: { @@ -138,7 +138,7 @@ _calendar.formatter.dateFormat = _appearance.headerDateFormat; BOOL usesUpperCase = (_appearance.caseOptions & 15) == FSCalendarCaseOptionsHeaderUsesUpperCase; NSString *text = nil; - switch (self.calendar.scope) { + switch (self.calendar.transitionCoordinator.representingScope) { case FSCalendarScopeMonth: { if (_scrollDirection == UICollectionViewScrollDirectionHorizontal) { // 多出的两项需要制空 diff --git a/FSCalendar/FSCalendarScopeHandle.m b/FSCalendar/FSCalendarScopeHandle.m index 6b7cbf5..6eb789c 100644 --- a/FSCalendar/FSCalendarScopeHandle.m +++ b/FSCalendar/FSCalendarScopeHandle.m @@ -8,7 +8,7 @@ #import "FSCalendarScopeHandle.h" #import "FSCalendar.h" -#import "FSCalendarAnimator.h" +#import "FSCalendarTransitionCoordinator.h" #import "FSCalendarDynamicHeader.h" #import "FSCalendarExtensions.h" @@ -66,13 +66,13 @@ - (void)handlePan:(id)sender { - [self.calendar.animator handleScopeGesture:sender]; + [self.calendar.transitionCoordinator handleScopeGesture:sender]; } - (void)setCalendar:(FSCalendar *)calendar { _calendar = calendar; - self.panGesture.delegate = self.calendar.animator; + self.panGesture.delegate = self.calendar.transitionCoordinator; } @end diff --git a/FSCalendar/FSCalendarAnimator.h b/FSCalendar/FSCalendarTransitionCoordinator.h similarity index 90% rename from FSCalendar/FSCalendarAnimator.h rename to FSCalendar/FSCalendarTransitionCoordinator.h index 45f0c74..eccbafd 100644 --- a/FSCalendar/FSCalendarAnimator.h +++ b/FSCalendar/FSCalendarTransitionCoordinator.h @@ -1,5 +1,5 @@ // -// FSCalendarAnimator.h +// FSCalendarTransitionCoordinator.h // FSCalendar // // Created by dingwenchao on 3/13/16. @@ -22,7 +22,7 @@ typedef NS_ENUM(NSUInteger, FSCalendarTransitionState) { FSCalendarTransitionStateFinishing, }; -@interface FSCalendarAnimator : NSObject +@interface FSCalendarTransitionCoordinator : NSObject @property (weak, nonatomic) FSCalendar *calendar; @property (weak, nonatomic) FSCalendarCollectionView *collectionView; @@ -33,6 +33,8 @@ typedef NS_ENUM(NSUInteger, FSCalendarTransitionState) { @property (assign, nonatomic) CGSize cachedMonthSize; +@property (readonly, nonatomic) FSCalendarScope representingScope; + - (instancetype)initWithCalendar:(FSCalendar *)calendar; - (void)performScopeTransitionFromScope:(FSCalendarScope)fromScope toScope:(FSCalendarScope)toScope animated:(BOOL)animated; diff --git a/FSCalendar/FSCalendarAnimator.m b/FSCalendar/FSCalendarTransitionCoordinator.m similarity index 96% rename from FSCalendar/FSCalendarAnimator.m rename to FSCalendar/FSCalendarTransitionCoordinator.m index baaadaa..70609df 100644 --- a/FSCalendar/FSCalendarAnimator.m +++ b/FSCalendar/FSCalendarTransitionCoordinator.m @@ -1,23 +1,22 @@ // -// FSCalendarAnimator.m +// FSCalendarTransitionCoordinator.m // FSCalendar // // Created by Wenchao Ding on 3/13/16. // Copyright © 2016 Wenchao Ding. All rights reserved. // -#import "FSCalendarAnimator.h" +#import "FSCalendarTransitionCoordinator.h" #import "FSCalendarExtensions.h" #import "FSCalendarDynamicHeader.h" #import -@interface FSCalendarAnimator () +@interface FSCalendarTransitionCoordinator () @property (readonly, nonatomic) FSCalendarTransitionAttributes *transitionAttributes; @property (strong , nonatomic) FSCalendarTransitionAttributes *pendingAttributes; @property (assign , nonatomic) CGFloat lastTranslation; -@property (assign , nonatomic) FSCalendarScope calendarScope; @property (strong , nonatomic) NSDate *calendarCurrentPage; - (void)performTransitionCompletionAnimated:(BOOL)animated; @@ -39,7 +38,7 @@ @end -@implementation FSCalendarAnimator +@implementation FSCalendarTransitionCoordinator - (instancetype)initWithCalendar:(FSCalendar *)calendar { @@ -152,7 +151,6 @@ self.lastTranslation = [panGesture translationInView:panGesture.view].y; if (self.transition == FSCalendarTransitionWeekToMonth) { - self.calendarScope = FSCalendarScopeMonth; self.calendarCurrentPage = self.pendingAttributes.targetPage; [self prelayoutForWeekToMonthTransition]; @@ -172,9 +170,6 @@ CGFloat minTranslation = CGRectGetHeight(self.pendingAttributes.targetBounds) - CGRectGetHeight(self.pendingAttributes.sourceBounds); translation = MAX(minTranslation, translation); translation = MIN(0, translation); - if (minTranslation == 0) { - NSLog(@"000"); - } CGFloat progress = translation/minTranslation; [CATransaction begin]; [CATransaction setDisableActions:YES]; @@ -217,15 +212,17 @@ translation = MIN(0, translation); CGFloat progress = translation/minTranslation; + [self.calendar willChangeValueForKey:@"scope"]; if (velocity >= 0) { - + [self.calendar fs_setUnsignedIntegerVariable:FSCalendarScopeMonth forKey:@"_scope"]; [self performBackwardTransition:self.transition fromProgress:progress]; } else { - + [self.calendar fs_setUnsignedIntegerVariable:FSCalendarScopeWeek forKey:@"_scope"]; [self performForwardTransition:self.transition fromProgress:progress]; } + [self.calendar didChangeValueForKey:@"scope"]; break; } case FSCalendarTransitionWeekToMonth: { @@ -234,15 +231,16 @@ translation = MIN(maxTranslation, translation); CGFloat progress = translation/maxTranslation; + [self.calendar willChangeValueForKey:@"scope"]; if (velocity >= 0) { - + [self.calendar fs_setUnsignedIntegerVariable:FSCalendarScopeMonth forKey:@"_scope"]; [self performForwardTransition:self.transition fromProgress:progress]; } else { - + [self.calendar fs_setUnsignedIntegerVariable:FSCalendarScopeWeek forKey:@"_scope"]; [self performBackwardTransition:self.transition fromProgress:progress]; - } + [self.calendar didChangeValueForKey:@"scope"]; break; } default: @@ -266,7 +264,7 @@ } // Start transition - self.state = FSCalendarTransitionStateChanging; + self.state = FSCalendarTransitionStateFinishing; FSCalendarTransitionAttributes *attr = self.transitionAttributes; self.pendingAttributes = attr; @@ -348,7 +346,7 @@ - (void)performBoundingRectTransitionFromMonth:(NSDate *)fromMonth toMonth:(NSDate *)toMonth duration:(CGFloat)duration { - if (self.calendarScope != FSCalendarScopeMonth) return; + if (self.calendar.scope != FSCalendarScopeMonth) return; NSInteger lastRowCount = [self.calendar.calculator numberOfRowsInMonth:fromMonth]; NSInteger currentRowCount = [self.calendar.calculator numberOfRowsInMonth:toMonth]; if (lastRowCount != currentRowCount) { @@ -499,16 +497,17 @@ #pragma mark - Private properties -- (void)setCalendarScope:(FSCalendarScope)calendarScope +- (FSCalendarScope)representingScope { - [self.calendar willChangeValueForKey:@"scope"]; - [self.calendar fs_setUnsignedIntegerVariable:calendarScope forKey:@"_scope"]; - [self.calendar didChangeValueForKey:@"scope"]; -} - -- (FSCalendarScope)calendarScope -{ - return self.calendar.scope; + switch (self.state) { + case FSCalendarTransitionStateIdle: { + return self.calendar.scope; + } + case FSCalendarTransitionStateChanging: + case FSCalendarTransitionStateFinishing: { + return FSCalendarScopeMonth; + } + } } - (void)setCalendarCurrentPage:(NSDate *)calendarCurrentPage @@ -563,7 +562,6 @@ switch (transition) { case FSCalendarTransitionMonthToWeek: { - self.calendarScope = FSCalendarScopeWeek; self.calendarCurrentPage = attr.targetPage; self.calendar.contentView.clipsToBounds = YES; @@ -587,8 +585,6 @@ } case FSCalendarTransitionWeekToMonth: { - self.calendarScope = FSCalendarScopeMonth; - [self performAlphaAnimationFrom:progress to:1 duration:0.4 exception:attr.focusedRowNumber completion:^{ [self performTransitionCompletionAnimated:YES]; }]; @@ -641,7 +637,6 @@ case FSCalendarTransitionWeekToMonth: { [self performAlphaAnimationFrom:progress to:0 duration:0.3 exception:self.pendingAttributes.focusedRowNumber completion:^{ - self.calendarScope = FSCalendarScopeWeek; self.calendarCurrentPage = self.pendingAttributes.sourcePage; [self performTransitionCompletion:FSCalendarTransitionMonthToWeek animated:YES];