From 717237b1c31576d42cdfb9521839a026dc70b198 Mon Sep 17 00:00:00 2001 From: Khoren Markosyan Date: Tue, 13 Sep 2016 14:30:52 +0400 Subject: [PATCH] Implemented new autoscrolling logic. --- .../iCarouselExampleViewController.m | 7 ++ iCarousel/iCarousel.h | 13 +++ iCarousel/iCarousel.m | 89 ++++++++++++++++++- 3 files changed, 108 insertions(+), 1 deletion(-) diff --git a/Examples/Basic iOS Example/iCarouselExampleViewController.m b/Examples/Basic iOS Example/iCarouselExampleViewController.m index 1d70d95ba9..022fdaa533 100644 --- a/Examples/Basic iOS Example/iCarouselExampleViewController.m +++ b/Examples/Basic iOS Example/iCarouselExampleViewController.m @@ -53,6 +53,13 @@ - (void)viewDidLoad _carousel.type = iCarouselTypeCoverFlow2; } +-(void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + + // Uncomment this line for testing autoscrolling. +// [_carousel start]; +} + - (void)viewDidUnload { [super viewDidUnload]; diff --git a/iCarousel/iCarousel.h b/iCarousel/iCarousel.h index d49c268203..3a037b5643 100644 --- a/iCarousel/iCarousel.h +++ b/iCarousel/iCarousel.h @@ -141,6 +141,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly, getter = isDragging) BOOL dragging; @property (nonatomic, readonly, getter = isDecelerating) BOOL decelerating; @property (nonatomic, readonly, getter = isScrolling) BOOL scrolling; +@property (nonatomic, assign) CGFloat autoscrollDelay; - (void)scrollByOffset:(CGFloat)offset duration:(NSTimeInterval)duration; - (void)scrollToOffset:(CGFloat)offset duration:(NSTimeInterval)duration; @@ -158,6 +159,12 @@ NS_ASSUME_NONNULL_BEGIN - (void)insertItemAtIndex:(NSInteger)index animated:(BOOL)animated; - (void)reloadItemAtIndex:(NSInteger)index animated:(BOOL)animated; +// Autoscroll methods +- (void)start; +- (void)stop; +- (void)previous; +- (void)next; + - (void)reloadData; @end @@ -195,6 +202,12 @@ NS_ASSUME_NONNULL_BEGIN - (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform; - (CGFloat)carousel:(iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value; +// Autoscroll delegates +- (void)carouselDidShowNext:(iCarousel *)carousel; +- (void)carouselDidShowPrevious:(iCarousel *)carousel; +- (void)carouselWillShowNext:(iCarousel *)carousel; +- (void)carouselWillShowPrevious:(iCarousel *)carousel; + @end NS_ASSUME_NONNULL_END diff --git a/iCarousel/iCarousel.m b/iCarousel/iCarousel.m index 707874a83a..19dcf6b3d4 100644 --- a/iCarousel/iCarousel.m +++ b/iCarousel/iCarousel.m @@ -122,6 +122,9 @@ @interface iCarousel () @property (nonatomic, assign) BOOL didDrag; @property (nonatomic, assign) NSTimeInterval toggleTime; +@property (atomic) BOOL doStop; +@property (atomic) BOOL isAnimating; + NSComparisonResult compareViewDepth(UIView *view1, UIView *view2, iCarousel *self); @end @@ -147,7 +150,11 @@ - (void)setUp _scrollToItemBoundary = YES; _ignorePerpendicularSwipes = YES; _centerItemWhenSelected = YES; - + + _doStop = YES; + _isAnimating = NO; + _autoscrollDelay = 2; + _contentView = [[UIView alloc] initWithFrame:self.bounds]; @@ -1768,6 +1775,13 @@ - (void)step [self pushAnimationState:YES]; [_delegate carouselDidEndScrollingAnimation:self]; [self popAnimationState]; + + _isAnimating = NO; + + if (!_doStop) { + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(next) object:nil]; + [self performSelector:@selector(next) withObject:nil afterDelay:_autoscrollDelay]; + } } } else if (_decelerating) @@ -2341,4 +2355,77 @@ - (void)keyDown:(NSEvent *)theEvent #endif + +#pragma mark - Autoscroll methods + +- (void)start +{ + _doStop = NO; + [self next]; +} + +- (void)stop +{ + _doStop = YES; + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(next) object:nil]; +} + +- (void)next +{ + if (!_isAnimating && (self.dataSource && _numberOfItems >1)) { + + if ([self.delegate respondsToSelector:@selector(carouselWillShowNext:)]) { + [self.delegate carouselWillShowNext:self]; + } + + // Next Image + NSUInteger nextIndex = (self.currentItemIndex+1) % _numberOfItems; + + // Animate + [self scrollToItemAtIndex:nextIndex animated:YES]; + + // Call delegate + if([self.delegate respondsToSelector:@selector(carouselDidShowNext:)]){ + dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, SCROLL_DURATION * NSEC_PER_SEC); + dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ + if (self.window){ + [self.delegate carouselDidShowNext:self]; + } + }); + } + } +} + +- (void)previous +{ + if (!_isAnimating && (self.dataSource && _numberOfItems >1)) { + + if ([self.delegate respondsToSelector:@selector(carouselWillShowPrevious:)]) { + [self.delegate carouselWillShowPrevious:self]; + } + + // Previous image + NSUInteger prevIndex; + if (self.currentItemIndex == 0){ + prevIndex = _numberOfItems - 1; + } else { + prevIndex = (self.currentItemIndex - 1) % _numberOfItems; + } + + // Animate + [self scrollToItemAtIndex:prevIndex animated:YES]; + + // Call delegate + if ([self.delegate respondsToSelector:@selector(carouselDidShowPrevious:)]) { + dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, SCROLL_DURATION * NSEC_PER_SEC); + dispatch_after(popTime, dispatch_get_main_queue(), ^(void) { + if (self.window) { + [self.delegate carouselDidShowPrevious:self]; + } + }); + } + } + +} + @end