TYPagerView.m 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. //
  2. // TYPagerView.m
  3. // TYPagerControllerDemo
  4. //
  5. // Created by tany on 2017/7/5.
  6. // Copyright © 2017年 tanyang. All rights reserved.
  7. //
  8. #import "TYPagerView.h"
  9. @interface TYPagerView ()<TYPagerViewLayoutDataSource, TYPagerViewLayoutDelegate> {
  10. // private
  11. struct {
  12. unsigned int willAppearViewForIndex :1;
  13. unsigned int didAppearViewForIndex :1;
  14. unsigned int willDisappearViewForIndex :1;
  15. unsigned int didDisappearViewForIndex :1;
  16. unsigned int transitionFromIndexToIndex :1;
  17. unsigned int transitionFromIndexToIndexProgress :1;
  18. unsigned int viewDidScroll: 1;
  19. unsigned int viewWillBeginScrolling: 1;
  20. unsigned int viewDidEndScrolling: 1;
  21. }_delegateFlags;
  22. }
  23. // Data
  24. @property (nonatomic, strong) TYPagerViewLayout<UIView *> *layout;
  25. @end
  26. @implementation TYPagerView
  27. #pragma mark - life cycle
  28. - (instancetype)initWithFrame:(CGRect)frame {
  29. if (self = [super initWithFrame:frame]) {
  30. self.backgroundColor = [UIColor clearColor];
  31. // prevent sysytem automaticallyAdjustsScrollViewInsets
  32. [self addFixAutoAdjustInsetScrollView];
  33. [self addLayoutScrollView];
  34. }
  35. return self;
  36. }
  37. - (instancetype)initWithCoder:(NSCoder *)aDecoder {
  38. if (self = [super initWithCoder:aDecoder]) {
  39. self.backgroundColor = [UIColor clearColor];
  40. // prevent sysytem automaticallyAdjustsScrollViewInsets
  41. [self addFixAutoAdjustInsetScrollView];
  42. [self addLayoutScrollView];
  43. }
  44. return self;
  45. }
  46. - (void)addFixAutoAdjustInsetScrollView {
  47. UIView *view = [[UIView alloc]init];
  48. [self addSubview:view];
  49. }
  50. - (void)addLayoutScrollView {
  51. UIScrollView *contentView = [[UIScrollView alloc]init];
  52. TYPagerViewLayout<UIView *> *layout = [[TYPagerViewLayout alloc]initWithScrollView:contentView];
  53. layout.dataSource = self;
  54. layout.delegate = self;
  55. [self addSubview:contentView];
  56. _layout = layout;
  57. _layout.scrollView.frame = self.bounds;
  58. }
  59. #pragma mark - getter && setter
  60. - (NSInteger)curIndex {
  61. return _layout.curIndex;
  62. }
  63. - (NSInteger)countOfPagerViews {
  64. return _layout.countOfPagerItems;
  65. }
  66. - (NSArray<UIView *> *)visibleViews {
  67. return _layout.visibleItems;
  68. }
  69. - (UIScrollView *)scrollView {
  70. return _layout.scrollView;
  71. }
  72. - (void)setContentInset:(UIEdgeInsets)contentInset {
  73. _contentInset = contentInset;
  74. [self setNeedsLayout];
  75. }
  76. - (void)setDelegate:(id<TYPagerViewDelegate>)delegate {
  77. _delegate = delegate;
  78. _delegateFlags.willAppearViewForIndex = [delegate respondsToSelector:@selector(pagerView:willAppearView:forIndex:)];
  79. _delegateFlags.didAppearViewForIndex = [delegate respondsToSelector:@selector(pagerView:didAppearView:forIndex:)];
  80. _delegateFlags.willDisappearViewForIndex = [delegate respondsToSelector:@selector(pagerView:willDisappearView:forIndex:)];
  81. _delegateFlags.didDisappearViewForIndex = [delegate respondsToSelector:@selector(pagerView:didDisappearView:forIndex:)];
  82. _delegateFlags.transitionFromIndexToIndex = [delegate respondsToSelector:@selector(pagerView:transitionFromIndex:toIndex:animated:)];
  83. _delegateFlags.transitionFromIndexToIndexProgress = [delegate respondsToSelector:@selector(pagerView:transitionFromIndex:toIndex:progress:)];
  84. _delegateFlags.viewDidScroll = [delegate respondsToSelector:@selector(pagerViewDidScroll:)];
  85. _delegateFlags.viewWillBeginScrolling = [delegate respondsToSelector:@selector(pagerViewWillBeginScrolling:animate:)];
  86. _delegateFlags.viewDidEndScrolling = [delegate respondsToSelector:@selector(pagerViewDidEndScrolling:animate:)];
  87. }
  88. #pragma mark - public
  89. - (void)updateData {
  90. [_layout updateData];
  91. }
  92. - (void)reloadData {
  93. [_layout reloadData];
  94. }
  95. - (void)scrollToViewAtIndex:(NSInteger)index animate:(BOOL)animate {
  96. [_layout scrollToItemAtIndex:index animate:animate];
  97. }
  98. - (UIView *)viewForIndex:(NSInteger)idx {
  99. return [_layout itemForIndex:idx];
  100. }
  101. - (void)registerClass:(Class)Class forViewWithReuseIdentifier:(NSString *)identifier {
  102. [_layout registerClass:Class forItemWithReuseIdentifier:identifier];
  103. }
  104. - (void)registerNib:(UINib *)nib forViewWithReuseIdentifier:(NSString *)identifier {
  105. [_layout registerNib:nib forItemWithReuseIdentifier:identifier];
  106. }
  107. - (UIView *)dequeueReusableViewWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index {
  108. return [_layout dequeueReusableItemWithReuseIdentifier:identifier forIndex:index];
  109. }
  110. #pragma mark - private
  111. - (void)willBeginScrollingAnimate:(BOOL)animate {
  112. if (_delegateFlags.viewWillBeginScrolling) {
  113. [_delegate pagerViewWillBeginScrolling:self animate:animate];
  114. }
  115. }
  116. - (void)didEndScrollingAnimate:(BOOL)animate {
  117. if (_delegateFlags.viewDidEndScrolling) {
  118. [_delegate pagerViewDidEndScrolling:self animate:animate];
  119. }
  120. }
  121. #pragma mark - TYPagerViewLayoutDataSource
  122. - (NSInteger)numberOfItemsInPagerViewLayout {
  123. return [_dataSource numberOfViewsInPagerView];
  124. }
  125. - (id)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout itemForIndex:(NSInteger)index prefetching:(BOOL)prefetching {
  126. return [_dataSource pagerView:self viewForIndex:index prefetching:prefetching];
  127. }
  128. - (UIView *)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout viewForItem:(id)item atIndex:(NSInteger)index {
  129. return item;
  130. }
  131. - (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout addVisibleItem:(id)item atIndex:(NSInteger)index {
  132. UIView *visibleView = item;
  133. if (_delegateFlags.willAppearViewForIndex) {
  134. [_delegate pagerView:self willAppearView:visibleView forIndex:index];
  135. }
  136. [pagerViewLayout.scrollView addSubview:visibleView];
  137. if (_delegateFlags.didAppearViewForIndex) {
  138. [_delegate pagerView:self didAppearView:visibleView forIndex:index];
  139. }
  140. }
  141. - (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout removeInVisibleItem:(id)item atIndex:(NSInteger)index {
  142. UIView *invisibleView = item;
  143. if (_delegateFlags.willDisappearViewForIndex) {
  144. [_delegate pagerView:self willDisappearView:invisibleView forIndex:index];
  145. }
  146. [invisibleView removeFromSuperview];
  147. if (_delegateFlags.didDisappearViewForIndex) {
  148. [_delegate pagerView:self didDisappearView:invisibleView forIndex:index];
  149. }
  150. }
  151. #pragma mark - TYPagerViewLayoutDelegate
  152. - (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex animated:(BOOL)animated {
  153. if (_delegateFlags.transitionFromIndexToIndex) {
  154. [_delegate pagerView:self transitionFromIndex:fromIndex toIndex:toIndex animated:animated];
  155. }
  156. }
  157. - (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress {
  158. if (_delegateFlags.transitionFromIndexToIndexProgress) {
  159. [_delegate pagerView:self transitionFromIndex:fromIndex toIndex:toIndex progress:progress];
  160. }
  161. }
  162. - (void)pagerViewLayoutDidScroll:(TYPagerViewLayout *)pagerViewLayout {
  163. if (_delegateFlags.viewDidScroll) {
  164. [_delegate pagerViewDidScroll:self];
  165. }
  166. }
  167. - (void)pagerViewLayoutWillBeginDragging:(TYPagerViewLayout *)pagerViewLayout {
  168. [self willBeginScrollingAnimate:YES];
  169. }
  170. - (void)pagerViewLayoutWillBeginScrollToView:(TYPagerViewLayout *)pagerViewLayout animate:(BOOL)animate {
  171. [self willBeginScrollingAnimate:animate];
  172. }
  173. - (void)pagerViewLayoutDidEndDecelerating:(TYPagerViewLayout *)pagerViewLayout {
  174. [self didEndScrollingAnimate:YES];
  175. }
  176. - (void)pagerViewLayoutDidEndScrollToView:(TYPagerViewLayout *)pagerViewLayout animate:(BOOL)animate {
  177. [self didEndScrollingAnimate:animate];
  178. }
  179. - (void)pagerViewLayoutDidEndScrollingAnimation:(TYPagerViewLayout *)pagerViewLayout {
  180. [self didEndScrollingAnimate:YES];
  181. }
  182. #pragma mark - layoutSubviews
  183. - (void)layoutSubviews {
  184. [super layoutSubviews];
  185. _layout.scrollView.frame = UIEdgeInsetsInsetRect(self.bounds,_contentInset);
  186. }
  187. - (void)dealloc {
  188. _layout = nil;
  189. }
  190. @end