CycleScrollView.m 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. //
  2. // CycleScrollView.m
  3. // PagedScrollView
  4. //
  5. // Created by 陈政 on 14-1-23.
  6. // Copyright (c) 2014年 Apple Inc. All rights reserved.
  7. //
  8. #import "CycleScrollView.h"
  9. #import "NSTimer+Addition.h"
  10. @interface CycleScrollView () <UIScrollViewDelegate>
  11. @property (nonatomic , assign) NSInteger currentPageIndex;
  12. @property (nonatomic , assign) NSInteger totalPageCount;
  13. @property (nonatomic , strong) NSMutableArray *contentViews;
  14. @property (nonatomic , strong) UIScrollView *scrollView;
  15. @property (nonatomic , strong) NSTimer *animationTimer;
  16. @property (nonatomic , assign) NSTimeInterval animationDuration;
  17. @end
  18. @implementation CycleScrollView
  19. @synthesize pageControl;
  20. - (void)setTotalPagesCount:(NSInteger (^)(void))totalPagesCount
  21. {
  22. _totalPageCount = totalPagesCount();
  23. if (_totalPageCount > 0) {
  24. if (self.hasOnlyTwoDateSource)
  25. {
  26. pageControl.numberOfPages = 2;
  27. }
  28. else
  29. {
  30. pageControl.numberOfPages = _totalPageCount;
  31. }
  32. [self configContentViews];
  33. [self.animationTimer resumeTimerAfterTimeInterval:self.animationDuration];
  34. }
  35. if (_totalPageCount <= 0) {
  36. [self.scrollView setScrollEnabled:NO];
  37. }
  38. else{
  39. [self.scrollView setScrollEnabled:YES];
  40. }
  41. }
  42. - (id)initWithFrame:(CGRect)frame animationDuration:(NSTimeInterval)animationDuration
  43. {
  44. self = [self initWithFrame:frame];
  45. if (animationDuration > 0.0) {
  46. self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:(self.animationDuration = animationDuration)
  47. target:self
  48. selector:@selector(animationTimerDidFired:)
  49. userInfo:nil
  50. repeats:YES];
  51. [self.animationTimer pauseTimer];
  52. }
  53. return self;
  54. }
  55. - (id)initWithFrame:(CGRect)frame
  56. {
  57. self = [super initWithFrame:frame];
  58. if (self) {
  59. // Initialization code
  60. self.autoresizesSubviews = YES;
  61. self.scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
  62. self.scrollView.autoresizingMask = 0xFF;
  63. self.scrollView.contentMode = UIViewContentModeCenter;
  64. self.scrollView.contentSize = CGSizeMake(3 * CGRectGetWidth(self.scrollView.frame), CGRectGetHeight(self.scrollView.frame));
  65. self.scrollView.delegate = self;
  66. self.scrollView.contentOffset = CGPointMake(CGRectGetWidth(self.scrollView.frame), 0);
  67. self.scrollView.pagingEnabled = YES;
  68. [self addSubview:self.scrollView];
  69. self.currentPageIndex = 0;
  70. // UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 120.0, 40.0)];
  71. // [view setBackgroundColor:[UIColor redColor]];
  72. // [self addSubview:view];
  73. // 初始化 pagecontrol
  74. self.pageControl = [[UIPageControl alloc] init]; // 初始化mypagecontrol
  75. [pageControl setFrame:CGRectMake(self.frame.size.width - 100, self.frame.size.height - 20, 80.0, 15.0)];
  76. if ([[UIDevice currentDevice].systemVersion floatValue] > 6.0)
  77. {
  78. [pageControl setPageIndicatorTintColor:[UIColor whiteColor]];
  79. [pageControl setCurrentPageIndicatorTintColor:[UIColor grayColor]];
  80. }
  81. pageControl.currentPage = 0;
  82. // [pageControl setBackgroundColor:[UIColor redColor]];
  83. [self addSubview:pageControl];
  84. }
  85. return self;
  86. }
  87. #pragma mark -
  88. #pragma mark - 私有函数
  89. - (void)configContentViews
  90. {
  91. [self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
  92. [self setScrollViewContentDataSource];
  93. NSInteger counter = 0;
  94. for (UIImageView *contentView in self.contentViews) {
  95. contentView.userInteractionEnabled = YES;
  96. UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(contentViewTapAction:)];
  97. [contentView addGestureRecognizer:tapGesture];
  98. CGRect rightRect = contentView.frame;
  99. rightRect.origin = CGPointMake(CGRectGetWidth(self.scrollView.frame) * (counter ++), 0);
  100. contentView.frame = rightRect;
  101. [self.scrollView addSubview:contentView];
  102. }
  103. [_scrollView setContentOffset:CGPointMake(_scrollView.frame.size.width, 0)];
  104. }
  105. /**
  106. * 设置scrollView的content数据源,即contentViews
  107. */
  108. - (void)setScrollViewContentDataSource
  109. {
  110. NSInteger previousPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex - 1];
  111. NSInteger rearPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex + 1];
  112. if (self.contentViews == nil) {
  113. self.contentViews = [@[] mutableCopy];
  114. }
  115. [self.contentViews removeAllObjects];
  116. if (self.fetchContentViewAtIndex) {
  117. [self.contentViews addObject:self.fetchContentViewAtIndex(previousPageIndex)];
  118. [self.contentViews addObject:self.fetchContentViewAtIndex(_currentPageIndex)];
  119. [self.contentViews addObject:self.fetchContentViewAtIndex(rearPageIndex)];
  120. }
  121. }
  122. - (NSInteger)getValidNextPageIndexWithPageIndex:(NSInteger)currentPageIndex;
  123. {
  124. if(currentPageIndex == -1) {
  125. return self.totalPageCount - 1;
  126. } else if (currentPageIndex == self.totalPageCount) {
  127. return 0;
  128. } else {
  129. return currentPageIndex;
  130. }
  131. }
  132. #pragma mark -
  133. #pragma mark - UIScrollViewDelegate
  134. - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
  135. {
  136. [self.animationTimer pauseTimer];
  137. }
  138. - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
  139. {
  140. [self.animationTimer resumeTimerAfterTimeInterval:self.animationDuration];
  141. }
  142. - (void)scrollViewDidScroll:(UIScrollView *)scrollView
  143. {
  144. int contentOffsetX = scrollView.contentOffset.x;
  145. if(contentOffsetX >= (2 * CGRectGetWidth(scrollView.frame))) {
  146. self.currentPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex + 1];
  147. // NSLog(@"next,当前页:%d",self.currentPageIndex);
  148. if (self.hasOnlyTwoDateSource)
  149. {
  150. pageControl.currentPage = self.currentPageIndex % 2;
  151. }
  152. else
  153. {
  154. pageControl.currentPage = self.currentPageIndex % self.totalPageCount;
  155. }
  156. [self configContentViews];
  157. }
  158. if(contentOffsetX <= 0) {
  159. self.currentPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex - 1];
  160. // NSLog(@"previous,当前页:%d",self.currentPageIndex);
  161. if (self.hasOnlyTwoDateSource)
  162. {
  163. pageControl.currentPage = self.currentPageIndex % 2;
  164. }
  165. else
  166. {
  167. pageControl.currentPage = self.currentPageIndex % self.totalPageCount;
  168. }
  169. [self configContentViews];
  170. }
  171. }
  172. - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
  173. {
  174. [scrollView setContentOffset:CGPointMake(CGRectGetWidth(scrollView.frame), 0) animated:YES];
  175. }
  176. #pragma mark -
  177. #pragma mark - 响应事件
  178. - (void)animationTimerDidFired:(NSTimer *)timer
  179. {
  180. CGPoint newOffset = CGPointMake(self.scrollView.contentOffset.x + CGRectGetWidth(self.scrollView.frame), self.scrollView.contentOffset.y);
  181. [self.scrollView setContentOffset:newOffset animated:YES];
  182. }
  183. - (void)contentViewTapAction:(UITapGestureRecognizer *)tap
  184. {
  185. if (self.TapActionBlock) {
  186. self.TapActionBlock(self.currentPageIndex);
  187. pageControl.currentPage = self.currentPageIndex;
  188. }
  189. }
  190. /*
  191. // Only override drawRect: if you perform custom drawing.
  192. // An empty implementation adversely affects performance during animation.
  193. - (void)drawRect:(CGRect)rect
  194. {
  195. // Drawing code
  196. }
  197. */
  198. @end