Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API for users to check and be notified of scrolling state #202

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions JTCalendar/JTCalendarDelegate.h
Expand Up @@ -61,11 +61,21 @@
*/
- (void)calendarDidLoadPreviousPage:(JTCalendarManager *)calendar;

/**
* Indicates the previous page finished scrolling after becoming the current page.
*/
- (void)calendarDidFinishScrollingToPreviousPage:(JTCalendarManager *)calendar;

/*!
* Indicate the next page became the current page.
*/
- (void)calendarDidLoadNextPage:(JTCalendarManager *)calendar;

/**
* Indicates the next page finished scrolling after becoming the current page.
*/
- (void)calendarDidFinishScrollingToNextPage:(JTCalendarManager *)calendar;

/*!
* Provide a view conforming to `JTCalendarPage` protocol, used as page for the contentView.
* Return an instance of `JTCalendarPageView` by default.
Expand Down
3 changes: 3 additions & 0 deletions JTCalendar/Managers/JTCalendarScrollManager.h
Expand Up @@ -27,5 +27,8 @@

- (void)updateMenuContentOffset:(CGFloat)percentage pageMode:(NSUInteger)pageMode;
- (void)updateHorizontalContentOffset:(CGFloat)percentage;
- (void)endDragging;
- (void)endDecelerating;
- (void)endHorizontalScrollingAnimation;

@end
27 changes: 27 additions & 0 deletions JTCalendar/Managers/JTCalendarScrollManager.m
Expand Up @@ -39,4 +39,31 @@ - (void)updateHorizontalContentOffset:(CGFloat)percentage
_horizontalContentView.contentOffset = CGPointMake(percentage * _horizontalContentView.contentSize.width, 0);
}

- (void)endDragging
{
if(![_horizontalContentView.delegate respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)]){
return;
}

[_horizontalContentView.delegate scrollViewDidEndDragging:_horizontalContentView willDecelerate:NO];
}

- (void)endDecelerating
{
if(![_horizontalContentView.delegate respondsToSelector:@selector(scrollViewDidEndDecelerating:)]){
return;
}

[_horizontalContentView.delegate scrollViewDidEndDecelerating:_horizontalContentView];
}

- (void)endHorizontalScrollingAnimation
{
if(![_horizontalContentView.delegate respondsToSelector:@selector(scrollViewDidEndScrollingAnimation:)]){
return;
}

[_horizontalContentView.delegate scrollViewDidEndScrollingAnimation:_horizontalContentView];
}

@end
2 changes: 2 additions & 0 deletions JTCalendar/Views/JTCalendarMenuView.h
Expand Up @@ -17,6 +17,8 @@

@property (nonatomic, readonly) UIScrollView *scrollView;

@property (nonatomic, assign, readonly) BOOL scrolling;

/*!
* Must be call if override the class
*/
Expand Down
28 changes: 28 additions & 0 deletions JTCalendar/Views/JTCalendarMenuView.m
Expand Up @@ -78,6 +78,15 @@ - (void)layoutSubviews
[self resizeViewsIfWidthChanged];
}

#pragma mark - Properties

- (BOOL)scrolling
{
return self.scrollView.dragging || self.scrollView.decelerating;
}

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if(_scrollView.contentSize.width <= 0){
Expand All @@ -87,6 +96,25 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView
[_manager.scrollManager updateHorizontalContentOffset:(_scrollView.contentOffset.x / _scrollView.contentSize.width)];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if(!decelerate){
[_manager.scrollManager endDragging];
}
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[_manager.scrollManager endDecelerating];
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
[_manager.scrollManager endHorizontalScrollingAnimation];
}

#pragma mark -

- (void)resizeViewsIfWidthChanged
{
CGSize size = self.frame.size;
Expand Down
2 changes: 2 additions & 0 deletions JTCalendar/Views/JTHorizontalCalendarView.h
Expand Up @@ -15,6 +15,8 @@

@property (nonatomic) NSDate *date;

@property (nonatomic, assign, readonly) BOOL scrolling;

/*!
* Must be call if override the class
*/
Expand Down
94 changes: 92 additions & 2 deletions JTCalendar/Views/JTHorizontalCalendarView.m
Expand Up @@ -16,7 +16,13 @@ typedef NS_ENUM(NSInteger, JTCalendarPageMode) {
JTCalendarPageModeCenterRight
};

@interface JTHorizontalCalendarView (){
typedef NS_ENUM(NSInteger, JTCalendarScrollingDirection) {
JTCalendarScrollingDirectionNone = 0,
JTCalendarScrollingDirectionPrevious,
JTCalendarScrollingDirectionNext
};

@interface JTHorizontalCalendarView () <UIScrollViewDelegate> {
CGSize _lastSize;

UIView<JTCalendarPage> *_leftView;
Expand All @@ -26,6 +32,11 @@ @interface JTHorizontalCalendarView (){
JTCalendarPageMode _pageMode;
}

// This class needs to hook into some of the UIScrollViewDelegate methods, so after it does that it will forward the messages on to the external delegate.
@property (nonatomic, weak) id<UIScrollViewDelegate> externalDelegate;
@property (nonatomic, assign) BOOL animatingOffset;
@property (nonatomic, assign) JTCalendarScrollingDirection scrollingDirection;

@end

@implementation JTHorizontalCalendarView
Expand Down Expand Up @@ -60,8 +71,24 @@ - (void)commonInit
self.showsVerticalScrollIndicator = NO;
self.pagingEnabled = YES;
self.clipsToBounds = YES;
// Deliberately using super here to avoid the overridden setter
[super setDelegate:self];
}

#pragma mark - Properties

- (void)setDelegate:(id<UIScrollViewDelegate>)delegate
{
self.externalDelegate = delegate;
}

- (BOOL)scrolling
{
return self.dragging || self.decelerating || self.animatingOffset;
}

#pragma mark -

- (void)layoutSubviews
{
[self resizeViewsIfWidthChanged];
Expand Down Expand Up @@ -232,6 +259,8 @@ - (void)loadPreviousPage
// Update dayViews becuase current month changed
[_rightView reload];
[_centerView reload];

self.scrollingDirection = JTCalendarScrollingDirectionPrevious;

if(_manager.delegate && [_manager.delegate respondsToSelector:@selector(calendarDidLoadPreviousPage:)]){
[_manager.delegate calendarDidLoadPreviousPage:_manager];
Expand Down Expand Up @@ -313,7 +342,9 @@ - (void)loadNextPage
// Update dayViews becuase current month changed
[_leftView reload];
[_centerView reload];


self.scrollingDirection = JTCalendarScrollingDirectionNext;

if(_manager.delegate && [_manager.delegate respondsToSelector:@selector(calendarDidLoadNextPage:)]){
[_manager.delegate calendarDidLoadNextPage:_manager];
}
Expand Down Expand Up @@ -446,4 +477,63 @@ - (void)updateMenuDates
nextDate:_rightView.date];
}

#pragma mark - UIScrollView

- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
{
if(animated){
self.animatingOffset = YES;
}
[super setContentOffset:contentOffset animated:animated];
}

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if(!decelerate){
[self notifyEndOfScrolling];
}

if(self.externalDelegate){
[self.externalDelegate scrollViewDidEndDragging:scrollView willDecelerate:decelerate];
}
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self notifyEndOfScrolling];

if(self.externalDelegate){
[self.externalDelegate scrollViewDidEndDecelerating:scrollView];
}
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
[self notifyEndOfScrolling];

if(self.externalDelegate){
[self.externalDelegate scrollViewDidEndScrollingAnimation:scrollView];
}
}

/**
* Private helper for the above delegate methods
*/
- (void)notifyEndOfScrolling
{
if(_manager.delegate){
if(self.scrollingDirection == JTCalendarScrollingDirectionPrevious && [_manager.delegate respondsToSelector:@selector(calendarDidFinishScrollingToPreviousPage:)]){
[_manager.delegate calendarDidFinishScrollingToPreviousPage:_manager];
}
else if(self.scrollingDirection == JTCalendarScrollingDirectionNext && [_manager.delegate respondsToSelector:@selector(calendarDidFinishScrollingToNextPage:)]){
[_manager.delegate calendarDidFinishScrollingToNextPage:_manager];
}
}

self.animatingOffset = NO;
self.scrollingDirection = JTCalendarScrollingDirectionNone;
}

@end