dkahgld

LPPageVC.m 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. //
  2. // LPPageVC.m
  3. // LPNavPageVCTest
  4. //
  5. // Created by LPDev on 16/4/19.
  6. // Copyright © 2016年 anonymous. All rights reserved.
  7. //
  8. #import "LPPageVC.h"
  9. #import "Masonry.h"
  10. #define SCREEN_SIZE [UIScreen mainScreen].bounds.size
  11. //#define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
  12. //#define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
  13. /**
  14. * segment的高度
  15. */
  16. const CGFloat LPPageVCSegmentHeight = 40.0f;
  17. /**
  18. * 预加载vc的个数
  19. */
  20. const NSInteger loadVcCount = 1;
  21. /**
  22. * 标签背景的高度 PS:两个样式
  23. */
  24. const CGFloat LPPageVCSegmentIndicatorHeight = 32.0f;
  25. const CGFloat LPPageVCSegmentIndicatorHeightLine = 3.0f;
  26. /**
  27. * 可见的最大的Pages
  28. */
  29. const NSInteger LPPageVCMaxVisiblePages = 6;
  30. @interface LPPageVC () <UIScrollViewDelegate> {
  31. UIView * _segmentContainerView; // Container 容器 - 上面的SegmentCV
  32. UIView * _contentContainerView; // Container 容器 - 下面的滚动视图CV
  33. UIView * _indicatorView; // indicator 指示器 - 标签下面的杠杠
  34. BOOL _doneLayout; // 完成 布局
  35. BOOL _editMode; // edit 状态
  36. }
  37. @property (nonatomic, assign) NSInteger numberOfContent;
  38. @property (nonatomic, assign) NSInteger currentIndex;
  39. @property (nonatomic, assign) NSInteger lastIndex;
  40. @property (nonatomic, strong) NSMutableArray * segmentTitles; // 标签数组
  41. @property (nonatomic, strong) NSMutableDictionary * reusableVCDic; // reusable 可再用的
  42. @property (nonatomic, assign) CGSize size; // 用来适配多字数
  43. @end
  44. @implementation LPPageVC
  45. - (instancetype)initWithCoder:(NSCoder *)aDecoder {
  46. self = [super initWithCoder:aDecoder];
  47. if (self) {
  48. // ..aDecoder
  49. }
  50. return self;
  51. }
  52. - (void)setSegmentStyle:(LPPageVCSegmentStyle)segmentStyle {
  53. _segmentStyle = segmentStyle;
  54. // 设置宽度和弧度
  55. if (_segmentStyle == LPPageVCSegmentStyleDefault) {
  56. _indicatorView.layer.cornerRadius = 4.0f;
  57. _indicatorView.layer.masksToBounds = YES;
  58. // NSLog(@"LPPageVCSegmentStyleDefault");
  59. }
  60. if (_segmentStyle == LPPageVCSegmentStyleLineHighlight) {
  61. _indicatorView.layer.cornerRadius = 0.0f;
  62. _indicatorView.layer.masksToBounds = NO;
  63. // NSLog(@"LPPageVCSegmentStyleLineHighlight");
  64. }
  65. }
  66. - (void)setLineBackground:(UIColor *)lineBackground {
  67. _lineBackground = lineBackground;
  68. _indicatorView.backgroundColor = _lineBackground;
  69. }
  70. - (void)viewDidLoad {
  71. [super viewDidLoad];
  72. [self defaultSetup];
  73. }
  74. #pragma mark defaultSetup - default setup - 默认设置
  75. - (void)defaultSetup {
  76. self.automaticallyAdjustsScrollViewInsets = NO;
  77. _editMode = LPPageVCEditModeDefault;
  78. _currentIndex = 0;
  79. // 接下来是创建UI .. 首先是创建 segment 的滚动视图
  80. _segmentScrollView = [[UIScrollView alloc] init];
  81. _segmentScrollView.showsHorizontalScrollIndicator = NO; // 是否显示水平滚动条
  82. _segmentScrollView.showsVerticalScrollIndicator = NO; // 是否显示垂直滚动条
  83. _segmentScrollView.scrollsToTop = NO; // To Top
  84. _segmentScrollView.bounces = YES;
  85. _segmentScrollView.backgroundColor = [UIColor clearColor];
  86. [self.view addSubview:_segmentScrollView];
  87. [_segmentScrollView mas_makeConstraints:^(MASConstraintMaker *make) {
  88. make.left.mas_equalTo(10);
  89. // make.left.mas_equalTo(0);
  90. // make.right.mas_equalTo(-40);
  91. make.right.mas_equalTo(-10);
  92. // 左和当前视图约束
  93. make.top.mas_equalTo(self.navBar.mas_bottom); // mas_topLayoutGuide 头部视图区域
  94. // 上和Top Nav约束
  95. make.height.mas_equalTo(LPPageVCSegmentHeight); // 高度
  96. // 高度等于自己设置的高度 - LPPageVCSegmentHeight
  97. }];
  98. #pragma mark - 创建editButton
  99. // edit按钮的背景视图
  100. // UIControl * editBgView = [[UIControl alloc] init];
  101. // [editBgView addTarget:self action:@selector(editButtonAction) forControlEvents:UIControlEventTouchUpInside];
  102. // editBgView.backgroundColor = [UIColor clearColor];
  103. //// editBgView.layer.shadowOpacity = 0.5;// 阴影透明度
  104. //// editBgView.layer.shadowColor = [UIColor grayColor].CGColor;// 阴影的颜色
  105. //// editBgView.layer.shadowRadius = 3;// 阴影扩散的范围控制
  106. //// editBgView.layer.shadowOffset = CGSizeMake(-10, 0);// 阴影的范围
  107. //
  108. // [self.view addSubview:editBgView];
  109. //
  110. // [editBgView mas_makeConstraints:^(MASConstraintMaker *make) {
  111. //
  112. // make.top.bottom.mas_equalTo(_segmentScrollView);
  113. // // 上下和_segmentScrollView对齐
  114. // make.left.mas_equalTo(_segmentScrollView.mas_right);
  115. // // 左和_segmentScrollView右边对齐
  116. // make.right.mas_equalTo(self.view);
  117. // // 右和当前视图对齐
  118. // make.width.mas_equalTo(_segmentScrollView.mas_height);
  119. // // 宽度等于_segmentScrollView的高度 - 也即是editButton是个正方形
  120. // }];
  121. //
  122. //
  123. // // edit按钮左边的横线
  124. //// UIView * lineView = [[UIView alloc] init];
  125. //// lineView.backgroundColor = [UIColor lightGrayColor];
  126. ////
  127. //// [editBgView addSubview:lineView];
  128. ////
  129. //// [lineView mas_makeConstraints:^(MASConstraintMaker *make) {
  130. ////
  131. //// make.left.top.bottom.mas_equalTo(editBgView);
  132. //// // 左 上 下 都和editBgView对齐
  133. //// make.width.mas_equalTo(1);
  134. //// // 但是这个横线的宽度仅仅为1 ..
  135. //// }];
  136. //
  137. //
  138. // // 创建edit按钮
  139. // UIButton * editButton = [UIButton buttonWithType:UIButtonTypeCustom];
  140. // [editButton setBackgroundImage:[UIImage imageNamed:@"home_classify_white"] forState:UIControlStateNormal];
  141. // [editButton addTarget:self action:@selector(editButtonAction) forControlEvents:UIControlEventTouchUpInside];
  142. //
  143. // [editBgView addSubview:editButton];
  144. //
  145. // [editButton mas_makeConstraints:^(MASConstraintMaker *make) {
  146. //
  147. // // 这就简单了 == editBgView
  148. // make.center.mas_equalTo(editBgView);
  149. // }];
  150. // PS 翻转一个add顺序
  151. // 杠杠内容容器视图
  152. _indicatorView = [[UIView alloc] init];
  153. [_segmentScrollView addSubview:_indicatorView];
  154. // sgment 内容容器视图
  155. _segmentContainerView = [[UIView alloc] init];
  156. [_segmentScrollView addSubview:_segmentContainerView];
  157. [_segmentContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
  158. // edges 其实就是top,left,bottom,right的一个简化
  159. make.edges.mas_equalTo(_segmentScrollView);
  160. // 高度 == _segmentScrollView == LPPageVCSegmentHeight
  161. make.height.mas_equalTo(_segmentScrollView.mas_height);
  162. }];
  163. // 内容视图
  164. _contentScrollView = [[UIScrollView alloc] init];
  165. _contentScrollView.showsHorizontalScrollIndicator = NO;
  166. _contentScrollView.scrollsToTop = NO;
  167. _contentScrollView.delegate = self;
  168. _contentScrollView.pagingEnabled = YES;
  169. _contentScrollView.bounces = NO;
  170. [self.view addSubview:_contentScrollView];
  171. [_contentScrollView mas_makeConstraints:^(MASConstraintMaker *make) {
  172. make.left.right.mas_equalTo(self.view);
  173. make.top.mas_equalTo(_segmentScrollView.mas_bottom);
  174. make.bottom.mas_equalTo(self.mas_bottomLayoutGuide);
  175. }];
  176. // 内容容器视图
  177. _contentContainerView = [[UIView alloc] init];
  178. [_contentScrollView addSubview:_contentContainerView];
  179. [_contentContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
  180. make.edges.mas_equalTo(_contentScrollView);
  181. make.height.mas_equalTo(_contentScrollView);
  182. }];
  183. // Code ..
  184. _segmentTitles = [[NSMutableArray alloc] init];
  185. _reusableVCDic = [[NSMutableDictionary alloc] init];
  186. _doneLayout = NO;
  187. }
  188. #pragma mark - reloadDataAtIndex:index
  189. - (void)reloadDataAtIndex:(NSUInteger)index {
  190. NSString * title = [_dataSource pageVC:self titleAtIndex:index];
  191. [_segmentTitles replaceObjectAtIndex
  192. :index withObject:title];
  193. UILabel * label = (UILabel *)[_segmentContainerView viewWithTag:1000 + index];
  194. label.text = title;
  195. UIViewController * oldVC = [_reusableVCDic objectForKey:@(index)];
  196. [oldVC removeFromParentViewController];
  197. [oldVC.view removeFromSuperview];
  198. UIViewController * newVC = [_dataSource pageVC:self viewControllerAtIndex:index];
  199. [self addChildViewController:newVC];
  200. UIView * contentBgView = [_contentContainerView viewWithTag:2000 + index];
  201. [contentBgView addSubview:newVC.view];
  202. [newVC.view mas_makeConstraints:^(MASConstraintMaker *make) {
  203. make.edges.mas_equalTo(contentBgView);
  204. }];
  205. [_reusableVCDic setObject:newVC forKey:@(index)];
  206. if ([_delegate respondsToSelector:@selector(pageVC:didChangeToIndex:fromIndex:)] && _currentIndex == index) {
  207. [_delegate pageVC:self didChangeToIndex:index fromIndex:-1];
  208. }
  209. }
  210. #pragma mark - reloadData
  211. - (void)reloadData {
  212. _doneLayout = NO;
  213. [_reusableVCDic removeAllObjects];
  214. _numberOfContent = [_dataSource numberOfContentForPageVC:self];
  215. if (!_numberOfContent) {
  216. return;
  217. }
  218. [_segmentTitles removeAllObjects];
  219. [_segmentContainerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
  220. [_contentContainerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
  221. [self.childViewControllers makeObjectsPerformSelector:@selector(removeFromParentViewController)];
  222. UIView * lastSegmentView = nil;
  223. UIView * lastContentView = nil;
  224. if ([_delegate respondsToSelector:@selector(pageVC:willChangeToIndex:fromIndex:)]) {
  225. [_delegate pageVC:self willChangeToIndex:0 fromIndex:-1];
  226. }
  227. _currentIndex = 0;
  228. for (NSInteger index = 0; index < _numberOfContent; ++index) {
  229. // load segment
  230. NSString * title = [_dataSource pageVC:self titleAtIndex:index];
  231. [_segmentTitles addObject:title];
  232. UILabel *label = [[UILabel alloc] init];
  233. label.userInteractionEnabled = YES;
  234. label.text = [NSString stringWithFormat:@"%@", title];
  235. label.textColor = _normalTextColor;
  236. label.font = [UIFont systemFontOfSize:14.0f];
  237. label.textAlignment = NSTextAlignmentCenter;
  238. label.highlightedTextColor = _higlightTextColor;
  239. label.tag = 1000 + index;
  240. [self.labelArr addObject:label];
  241. // 改进适配字数
  242. CGSize size = [label.text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16.0f]}];
  243. self.size = size;
  244. // NSLog(@"标签的宽度是 - %f",size.width);
  245. UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapSegmentItemAction:)];
  246. [label addGestureRecognizer:tapGesture];
  247. [_segmentContainerView insertSubview:label aboveSubview:_indicatorView];
  248. [label mas_makeConstraints:^(MASConstraintMaker *make) {
  249. make.top.bottom.mas_equalTo(_segmentContainerView);
  250. if (lastSegmentView) {
  251. make.left.mas_equalTo(lastSegmentView.mas_right);
  252. } else {
  253. make.left.mas_equalTo(_segmentContainerView.mas_left);
  254. }
  255. CGSize sizeTest = self.size;
  256. sizeTest.width = sizeTest.width + 12;
  257. make.width.mas_equalTo(sizeTest);
  258. // if (SCREEN_WIDTH > 375.0f) {
  259. //
  260. // make.width.mas_equalTo(62);
  261. //
  262. // } else {
  263. //
  264. // make.width.mas_equalTo(66);
  265. // }
  266. }];
  267. lastSegmentView = label;
  268. UIView * view = [[UIView alloc] init];
  269. view.tag = 2000 + index;
  270. [_contentContainerView addSubview:view];
  271. [view mas_makeConstraints:^(MASConstraintMaker *make) {
  272. make.top.bottom.mas_equalTo(_contentContainerView);
  273. if (lastContentView) {
  274. make.left.mas_equalTo(lastContentView.mas_right);
  275. } else {
  276. make.left.mas_equalTo(_contentContainerView.mas_left);
  277. }
  278. make.width.mas_equalTo(CGRectGetWidth([[UIScreen mainScreen] bounds]));
  279. }];
  280. lastContentView = view;
  281. if (index < loadVcCount) {
  282. UIViewController * controller = [_dataSource pageVC:self viewControllerAtIndex:index];
  283. [self addChildViewController:controller];
  284. [_reusableVCDic setObject:controller forKey:@(index)];
  285. [view addSubview:controller.view];
  286. [controller.view mas_makeConstraints:^(MASConstraintMaker *make) {
  287. make.edges.mas_equalTo(view);
  288. }];
  289. }
  290. }
  291. //
  292. // UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, self.navigationBar.height+LPPageVCSegmentHeight-0.5, SCREEN_WIDTH, 0.5)];
  293. // line.backgroundColor = [UIColor YHColorWithHex:0xf5f4f4];
  294. // [self.view addSubview:line];
  295. UIView *line = [[UIView alloc] init];
  296. self.bottomLine = line;
  297. line.backgroundColor = [UIColor YHColorWithHex:0xf5f4f4];
  298. line.hidden = YES;
  299. [self.view addSubview:line];
  300. [line mas_makeConstraints:^(MASConstraintMaker *make) {
  301. make.left.right.mas_equalTo(0);
  302. make.height.mas_equalTo(0.5);
  303. make.top.mas_equalTo(_segmentScrollView.mas_bottom);
  304. }];
  305. [_segmentContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
  306. make.right.mas_equalTo(lastSegmentView.mas_right);
  307. }];
  308. [_contentContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
  309. make.right.mas_equalTo(lastContentView.mas_right);
  310. }];
  311. UILabel *currentLabel = (UILabel *)[_segmentContainerView viewWithTag:1000 + _currentIndex];
  312. currentLabel.font=[UIFont systemFontOfSize:16];
  313. currentLabel.highlighted = YES;
  314. [self.view layoutIfNeeded];
  315. CGRect frame = currentLabel.frame;
  316. if (_segmentStyle == LPPageVCSegmentStyleDefault) {
  317. _indicatorView.frame = CGRectMake(CGRectGetMinX(frame) + 6, CGRectGetHeight(frame)-LPPageVCSegmentIndicatorHeight, CGRectGetWidth(frame) - 12, LPPageVCSegmentIndicatorHeight - 8);
  318. }
  319. if (_segmentStyle == LPPageVCSegmentStyleLineHighlight) {
  320. _indicatorView.frame = CGRectMake(CGRectGetMinX(frame)+6, CGRectGetHeight(frame)-LPPageVCSegmentIndicatorHeightLine, CGRectGetWidth(frame)-12, LPPageVCSegmentIndicatorHeightLine);
  321. }
  322. _contentScrollView.contentOffset = CGPointMake(0, 0);
  323. if ([_delegate respondsToSelector:@selector(pageVC:didChangeToIndex:fromIndex:)]) {
  324. [_delegate pageVC:self didChangeToIndex:0 fromIndex:-1];
  325. }
  326. }
  327. - (void)tapSegmentItemAction:(UITapGestureRecognizer *)gesture {
  328. UIView *view = [gesture view];
  329. NSUInteger index = view.tag - 1000;
  330. if ([_delegate respondsToSelector:@selector(pageVC:didClickAtIndex:)]) {
  331. [_delegate pageVC:self didClickAtIndex:index];
  332. }
  333. [_contentScrollView setContentOffset:CGPointMake(index * CGRectGetWidth(_contentScrollView.frame), 0) animated:YES];
  334. }
  335. #pragma mark -------------- public ---------
  336. - (void)setSelectedIndex:(NSInteger)index {
  337. [_contentScrollView setContentOffset:CGPointMake(index * CGRectGetWidth(_contentScrollView.frame), 0) animated:YES];
  338. }
  339. #pragma mark - Setter & Getter
  340. - (void)setDataSource:(id<LPPageVCDataSource>)dataSource {
  341. if (_dataSource != dataSource) {
  342. _dataSource = dataSource;
  343. if (_dataSource) {
  344. [self reloadData];
  345. }
  346. }
  347. }
  348. - (void)setCurrentIndex:(NSInteger)currentIndex {
  349. if (_currentIndex != currentIndex) {
  350. if ([_delegate respondsToSelector:@selector(pageVC:willChangeToIndex:fromIndex:)]) {
  351. [_delegate pageVC:self willChangeToIndex:currentIndex fromIndex:_currentIndex];
  352. }
  353. UILabel *oldLabel = (UILabel *)[_segmentContainerView viewWithTag:1000 + _currentIndex];
  354. UILabel *newLable = (UILabel *)[_segmentContainerView viewWithTag:1000 + currentIndex];
  355. oldLabel.highlighted = NO;
  356. oldLabel.font=[UIFont systemFontOfSize:14];
  357. newLable.font=[UIFont systemFontOfSize:16];
  358. newLable.highlighted = YES;
  359. _lastIndex = _currentIndex;
  360. _currentIndex = currentIndex;
  361. [UIView animateWithDuration:0.3 animations:^{
  362. UILabel *currentLabel = (UILabel *)[_segmentContainerView viewWithTag:1000 + _currentIndex];
  363. CGRect frame = currentLabel.frame;
  364. if (_segmentStyle == LPPageVCSegmentStyleDefault) {
  365. _indicatorView.frame = CGRectMake(CGRectGetMinX(frame) + 6, CGRectGetHeight(frame)-LPPageVCSegmentIndicatorHeight, CGRectGetWidth(frame) - 12, LPPageVCSegmentIndicatorHeight - 8);
  366. }
  367. if (_segmentStyle == LPPageVCSegmentStyleLineHighlight) {
  368. _indicatorView.frame = CGRectMake(CGRectGetMinX(frame)+6, CGRectGetHeight(frame)-LPPageVCSegmentIndicatorHeightLine, CGRectGetWidth(frame)-12, LPPageVCSegmentIndicatorHeightLine);
  369. }
  370. }];
  371. [self updateSegmentContentOffset];
  372. if ([_delegate respondsToSelector:@selector(pageVC:didChangeToIndex:fromIndex:)]) {
  373. [_delegate pageVC:self didChangeToIndex:_currentIndex fromIndex:_lastIndex];
  374. }
  375. }
  376. }
  377. - (UIViewController *)viewControllerAtIndex:(NSUInteger)index {
  378. if (index >= _numberOfContent) {
  379. return nil;
  380. }
  381. return _reusableVCDic[@(index)];
  382. }
  383. #pragma mark - Private Function
  384. - (void)updateSegmentContentOffset {
  385. UILabel *currentLabel = (UILabel *)[_segmentContainerView viewWithTag:1000 + _currentIndex];
  386. CGRect rect = currentLabel.frame;
  387. CGFloat midX = CGRectGetMidX(rect);
  388. CGFloat offset = 0;
  389. CGFloat contentWidth = _segmentScrollView.contentSize.width;
  390. CGFloat halfWidth = CGRectGetWidth(_segmentScrollView.bounds) / 2;
  391. if (midX < (CGRectGetWidth(_segmentScrollView.bounds) / 6*5)) {
  392. offset = 0;
  393. } else if (midX > contentWidth - halfWidth) {
  394. offset = contentWidth - 2 * halfWidth;
  395. } else {
  396. offset = midX - halfWidth;
  397. }
  398. [_segmentScrollView setContentOffset:CGPointMake(offset, 0) animated:YES];
  399. }
  400. - (void)transitionFromIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex
  401. {
  402. if (fromIndex == toIndex) {
  403. return;
  404. }
  405. NSInteger removeIndex = 0;
  406. NSInteger addIndex = 0;
  407. // NSLog(@"%@ - %@", @(fromIndex), @(toIndex));
  408. if (toIndex > fromIndex) {
  409. removeIndex = fromIndex - 1;
  410. addIndex = toIndex + 1;
  411. } else {
  412. removeIndex = fromIndex + 1;
  413. addIndex = toIndex - 1;
  414. }
  415. if (addIndex >= 0 && addIndex < _numberOfContent) {
  416. if (!_reusableVCDic[@(addIndex)]) {
  417. UIViewController *toController = [_dataSource pageVC:self viewControllerAtIndex:addIndex];
  418. [self addChildViewController:toController];
  419. [_reusableVCDic setObject:toController forKey:@(addIndex)];
  420. UIView *contentBgView = [_contentContainerView viewWithTag:2000 + addIndex];
  421. [contentBgView addSubview:toController.view];
  422. [toController.view mas_makeConstraints:^(MASConstraintMaker *make) {
  423. make.edges.mas_equalTo(contentBgView);
  424. }];
  425. }
  426. }
  427. if (!_reusableVCDic[@(toIndex)]) {
  428. UIViewController *toController = [_dataSource pageVC:self viewControllerAtIndex:toIndex];
  429. [self addChildViewController:toController];
  430. [_reusableVCDic setObject:toController forKey:@(toIndex)];
  431. UIView *contentBgView = [_contentContainerView viewWithTag:2000 + toIndex];
  432. [contentBgView addSubview:toController.view];
  433. [toController.view mas_makeConstraints:^(MASConstraintMaker *make) {
  434. make.edges.mas_equalTo(contentBgView);
  435. }];
  436. }
  437. if (removeIndex >= 0 && removeIndex < _numberOfContent && [_reusableVCDic allKeys].count > LPPageVCMaxVisiblePages) {
  438. UIViewController *fromController = _reusableVCDic[@(removeIndex)];
  439. [fromController removeFromParentViewController];
  440. [fromController.view removeFromSuperview];
  441. [_reusableVCDic removeObjectForKey:@(removeIndex)];
  442. }
  443. [self setCurrentIndex:toIndex];
  444. }
  445. #pragma mark - ScrollView Delegate
  446. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  447. }
  448. // 其实是走的 ScrollView Delegate
  449. - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
  450. NSInteger contentOffsetX = scrollView.contentOffset.x;
  451. NSInteger index = floor((contentOffsetX - CGRectGetWidth(scrollView.frame) / 2) / CGRectGetWidth(scrollView.frame))+1;
  452. [self transitionFromIndex:_currentIndex toIndex:index];
  453. }
  454. - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
  455. NSInteger contentOffsetX = scrollView.contentOffset.x;
  456. NSInteger index = floor((contentOffsetX - CGRectGetWidth(scrollView.frame) / 2) / CGRectGetWidth(scrollView.frame))+1;
  457. [self transitionFromIndex:_currentIndex toIndex:index];
  458. }
  459. #pragma mark - Button Action
  460. - (void)editButtonAction {
  461. _editMode = 1 - _editMode;
  462. if ([_delegate respondsToSelector:@selector(pageVC:didClickEditMode:)]) {
  463. [_delegate pageVC:self didClickEditMode:_editMode];
  464. }
  465. }
  466. - (void)didReceiveMemoryWarning {
  467. [super didReceiveMemoryWarning];
  468. }
  469. - (NSMutableArray *)labelArr {
  470. if (!_labelArr) {
  471. _labelArr = [NSMutableArray array];
  472. }
  473. return _labelArr;
  474. }
  475. /*
  476. #pragma mark - Navigation
  477. // In a storyboard-based application, you will often want to do a little preparation before navigation
  478. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  479. // Get the new view controller using [segue destinationViewController].
  480. // Pass the selected object to the new view controller.
  481. }
  482. */
  483. @end