财神随手记账

HPSlideSegmentView.m 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. //
  2. // HPSlideSegmentView.m
  3. // HPSlideSegmentView
  4. //
  5. // Created by 何鹏 on 17/6/12.
  6. // Copyright © 2017年 何鹏. All rights reserved.
  7. //
  8. #import "HPSlideSegmentView.h"
  9. #import "UIView+HPSlideSegmentRect.h"
  10. #import "HPSlideSegmentLogic.h"
  11. #import "HPCacheListManage.h"
  12. #import "HPSegmentEnum.h"
  13. #import "HPKVOMange.h"
  14. #import "HPScrollView.h"
  15. @interface HPSlideSegmentView ()<UIScrollViewDelegate,NSCacheDelegate,HPCacheListManageDelegate>
  16. @property(nonatomic,strong) HPScrollView *viewContrllerScrollerView;
  17. @property(nonatomic,strong) HPSlideModel *slideLeft;
  18. @property(nonatomic,strong) HPSlideModel *slideCentre;
  19. @property(nonatomic,strong) HPSlideModel *slideRight;
  20. @property(nonatomic,assign) NSUInteger showCount;
  21. @property(nonatomic,assign) BOOL scrollViewMove;
  22. @property(nonatomic,strong) HPCacheListManage *cacheListMange;
  23. @property(nonatomic,strong) HPKVOMange *kvoMange;
  24. @property(nonatomic,weak) UIScrollView *centreScrollerView;//滑动到中间
  25. @property(nonatomic,assign) CGFloat privateChangeCahePoint;
  26. @end
  27. @interface HPSlideModel ()
  28. /**
  29. 显示的ViewController
  30. */
  31. @property(nonatomic,strong) UIViewController *showViewController;
  32. /**
  33. ViewController 上面 的scrollView
  34. */
  35. @property(nonatomic,strong) UIScrollView *mainSlideScrollView;
  36. @end
  37. @implementation HPSlideSegmentView
  38. {
  39. NSUInteger _pageIndex;
  40. }
  41. -(void)layoutSubviews{
  42. [super layoutSubviews];
  43. }
  44. -(void)updateLayout
  45. {
  46. //更新布局
  47. [self layoutWithView];
  48. [self updateLayout:0];
  49. }
  50. -(void)layoutWithView
  51. {
  52. if (self.showCount==0) {
  53. return ;
  54. }
  55. if (self.showCount==1)
  56. {
  57. [self layoutWithScrollerAddView:self.viewContrllerScrollerView
  58. left:self.slideLeft
  59. centre:nil
  60. right:nil
  61. scrollerViewWithWidth:self.viewContrllerScrollerView.width];
  62. }
  63. else if(self.showCount==2)
  64. {
  65. [self layoutWithScrollerAddView:self.viewContrllerScrollerView
  66. left:self.slideLeft
  67. centre:self.slideCentre
  68. right:nil
  69. scrollerViewWithWidth:self.viewContrllerScrollerView.width];
  70. }
  71. else if (self.showCount>=3)
  72. {
  73. [self layoutWithScrollerAddView:self.viewContrllerScrollerView
  74. left:self.slideLeft
  75. centre:self.slideCentre
  76. right:self.slideRight
  77. scrollerViewWithWidth:self.viewContrllerScrollerView.width];
  78. }
  79. }
  80. -(void)layoutWithScrollerAddView:(UIScrollView *)addView
  81. left:(UIView *)left
  82. centre:(UIView *)centre
  83. right:(UIView *)right
  84. scrollerViewWithWidth:(CGFloat)scrollerViewWidth
  85. {
  86. CGFloat width = self.viewContrllerScrollerView.width;
  87. CGFloat height = self.viewContrllerScrollerView.height;
  88. left.frame=CGRectMake(0, 0, width, height);
  89. [addView addSubview:left];
  90. centre.frame=CGRectMake(scrollerViewWidth, 0, width, height);
  91. [addView addSubview:centre];
  92. right.frame=CGRectMake(2*scrollerViewWidth, 0, width, height);
  93. [addView addSubview:right];
  94. }
  95. -(void)updateLayout:(NSUInteger)pageIndex
  96. {
  97. [self updateLayout:pageIndex updateDelegate:YES];
  98. }
  99. -(void)updateScrollerViewWidthWidth:(NSUInteger)arrayCount
  100. {
  101. self.viewContrllerScrollerView.frame=CGRectMake(0, 0, self.width, self.height);
  102. CGFloat sizeWidth=[HPSlideSegmentLogic scrollViewWidth:_viewContrllerScrollerView.width dataArrayCount:arrayCount];
  103. self.viewContrllerScrollerView.contentSize=CGSizeMake(sizeWidth, self.height);
  104. [self addSubview:_viewContrllerScrollerView];
  105. _showCount = arrayCount;
  106. [self updateLayout];
  107. }
  108. #pragma mark - scrollerViewDelegate
  109. -(void)scrollViewDidScroll:(UIScrollView *)scrollView
  110. {
  111. if ([self.gestrueClashDelegate respondsToSelector:@selector(hp_slideWithGestureClash:)]) {
  112. [self.gestrueClashDelegate hp_slideWithGestureClash:NO];
  113. }
  114. [_viewContrllerScrollerView setDelaysContentTouches:NO];
  115. [_viewContrllerScrollerView setCanCancelContentTouches:NO];
  116. _pageIndex = scrollView.contentOffset.x/_viewContrllerScrollerView.width;
  117. CGPoint startOffset = CGPointMake(_pageIndex * _viewContrllerScrollerView.width, 0);
  118. [HPSlideSegmentLogic scrollView:_viewContrllerScrollerView
  119. currentIndex:_pageIndex
  120. startOffset:startOffset
  121. dataArray:_showCount
  122. boardBlock:^{
  123. [self changeWithScrollView:_viewContrllerScrollerView];
  124. } moduleBlock:^(NSUInteger nowIndex, NSUInteger readyIndex, CGFloat movePercent) {
  125. if ([self.delegate respondsToSelector:@selector(hp_slideWithNowIndex:readyIndex:movePercent:)]) {
  126. [self.delegate hp_slideWithNowIndex:nowIndex readyIndex:readyIndex movePercent:movePercent];
  127. }
  128. }];
  129. }
  130. -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
  131. {
  132. _pageIndex = scrollView.contentOffset.x/_viewContrllerScrollerView.width;
  133. }
  134. -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
  135. {
  136. if ([self.gestrueClashDelegate respondsToSelector:@selector(hp_slideWithGestureClash:)]) {
  137. [self.gestrueClashDelegate hp_slideWithGestureClash:YES];
  138. }
  139. }
  140. -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
  141. {
  142. _pageIndex = scrollView.contentOffset.x/_viewContrllerScrollerView.width;
  143. [self.delegate hp_slideWithNowIndex:_pageIndex readyIndex:_pageIndex movePercent:1];
  144. if ([self.gestrueClashDelegate respondsToSelector:@selector(hp_slideWithGestureClash:)]) {
  145. [self.gestrueClashDelegate hp_slideWithGestureClash:YES];
  146. }
  147. }
  148. -(void)changeWithScrollView:(UIScrollView *)scrollView
  149. {
  150. CGPoint startOffset = CGPointMake(_pageIndex * _viewContrllerScrollerView.width, 0);
  151. [HPSlideSegmentLogic slideSuperView:_viewContrllerScrollerView.width
  152. scrollView:_viewContrllerScrollerView
  153. currentIndex:_pageIndex
  154. startOffset:startOffset
  155. dataArray:_showCount
  156. changeIndex:^(HPNumber left, HPNumber centre, HPNumber right, CGPoint startPoint) {
  157. [self changeStatusLeft:left centre:centre right:right updateCreatNifomation:NO];
  158. }];
  159. }
  160. -(void)currenSlideScrollView
  161. {
  162. if (_showCount==2) {
  163. if (_pageIndex==0) {
  164. [self addObserver:_slideLeft pageIndex:_pageIndex];
  165. }
  166. else if (_pageIndex==self.showCount-1)
  167. {
  168. [self addObserver:_slideCentre pageIndex:_pageIndex];
  169. }
  170. }
  171. else
  172. {
  173. if (_pageIndex==0) {
  174. [self addObserver:_slideLeft pageIndex:_pageIndex];
  175. }
  176. else if (_pageIndex==self.showCount-1)
  177. {
  178. [self addObserver:_slideRight pageIndex:_pageIndex];
  179. }
  180. else
  181. {
  182. [self addObserver:_slideCentre pageIndex:_pageIndex];
  183. }
  184. }
  185. }
  186. -(void)changeStatusLeft:(HPNumber)left centre:(HPNumber)centre right:(HPNumber)right updateCreatNifomation:(BOOL)update
  187. {
  188. [self removeWithLayout:_slideLeft];
  189. [self removeWithLayout:_slideCentre];
  190. [self removeWithLayout:_slideRight];
  191. [self.cacheListMange addCacheWithLeft:ObjcWithKeyStructMake(left.number, LEFTTYPE)
  192. Centre:ObjcWithKeyStructMake(centre.number, CENTRETYPE)
  193. Right:ObjcWithKeyStructMake(right.number, RIGHTTYPE)
  194. updateContent:update];
  195. }
  196. +(void)layoutWithView:(HPSlideModel *)slideModel cacheSlideModel:(HPSlideModel *)cacheSlideModel pointIndex:(NSUInteger)index
  197. {
  198. if (cacheSlideModel.showViewController!=nil) {
  199. slideModel.showViewController=cacheSlideModel.showViewController;
  200. slideModel.showViewController.view.frame=CGRectMake(0, 0, slideModel.width, slideModel.height);
  201. slideModel.frame = CGRectMake(index * slideModel.width, 0, slideModel.width, slideModel.height);
  202. [slideModel addSubview:cacheSlideModel.showViewController.view];
  203. }
  204. // [slideModel showViewController:cacheSlideModel.showViewController pointIndex:index];
  205. slideModel.mainSlideScrollView=cacheSlideModel.mainSlideScrollView;;
  206. }
  207. -(void)removeWithLayout:(HPSlideModel *)slideView
  208. {
  209. if (slideView==nil) {
  210. return;
  211. }
  212. [slideView.showViewController.view removeFromSuperview];
  213. slideView.showViewController=nil;
  214. }
  215. -(void)updateLayout:(NSUInteger)pageIndex updateDelegate:(BOOL)update
  216. {
  217. _pageIndex=[HPSlideSegmentLogic arraCount:_showCount index:pageIndex];
  218. [HPSlideSegmentLogic currentIndex:_pageIndex
  219. arrayCount:_showCount
  220. scrollView:_viewContrllerScrollerView
  221. slideSuperView:_viewContrllerScrollerView.width
  222. changeIndex:^(HPNumber left, HPNumber centre, HPNumber right, CGPoint startPoint) {
  223. [self changeStatusLeft:left centre:centre right:right updateCreatNifomation:YES];
  224. _viewContrllerScrollerView.contentOffset = CGPointMake(_pageIndex * _viewContrllerScrollerView.width, 0);
  225. }];
  226. if ([self.gestrueClashDelegate respondsToSelector:@selector(hp_slideWithGestureClash:)]) {
  227. [self.gestrueClashDelegate hp_slideWithGestureClash:YES];
  228. }
  229. }
  230. -(void)addObserver:(HPSlideModel *)slideModel pageIndex:(NSUInteger)index
  231. {
  232. _centreScrollerView = slideModel.mainSlideScrollView;
  233. if (_centreScrollerView==nil) {
  234. return;
  235. }
  236. [self.kvoMange addObserverWithObject:_centreScrollerView
  237. blockWeak:self
  238. addObserver:^(HPSlideSegmentView *weakObj) {
  239. [weakObj.centreScrollerView addObserver:weakObj
  240. forKeyPath:@"contentOffset"
  241. options:NSKeyValueObservingOptionNew
  242. context:nil];
  243. }];
  244. }
  245. #pragma mark - <HPCacheListManageDelegate>
  246. -(void)removeWithCacheObj:(id)Obj
  247. {
  248. HPSlideModel *cacheSlideModel=Obj;
  249. if (cacheSlideModel==nil) {
  250. return;
  251. }
  252. [self.kvoMange removeObserverWithObject:cacheSlideModel.mainSlideScrollView
  253. blockWeak:self
  254. addObserver:^(HPSlideSegmentView *weakObj) {
  255. [cacheSlideModel.mainSlideScrollView removeObserver:self forKeyPath:@"contentOffset"];
  256. }];
  257. [cacheSlideModel.showViewController.view removeFromSuperview];
  258. cacheSlideModel.showViewController=nil;
  259. [cacheSlideModel.mainSlideScrollView removeFromSuperview];
  260. cacheSlideModel.mainSlideScrollView=nil;
  261. cacheSlideModel=nil;
  262. }
  263. -(id)hp_notCahceCreat:(id)cacheObj pageIndex:(NSUInteger)key{
  264. HPSlideModel *cacheSlideModel=cacheObj;
  265. if ([self.dataSource respondsToSelector:@selector(hp_slideListWithViewController:index:)]) {
  266. if (cacheSlideModel==nil) {
  267. cacheSlideModel=[[HPSlideModel alloc] init];
  268. }
  269. cacheSlideModel.showViewController = [self.dataSource hp_slideListWithViewController:cacheSlideModel index:key];
  270. [self getControllerWithScrollView:cacheSlideModel];
  271. }
  272. return cacheSlideModel;
  273. }
  274. -(void)hp_cacheWithLayout:(id)cacheObje direction:(DirectionType)direction page:(NSUInteger)key{
  275. HPSlideModel *cacheSlideModel=cacheObje;
  276. switch (direction) {
  277. case LEFTTYPE:
  278. {
  279. [HPSlideSegmentView layoutWithView:self.slideLeft cacheSlideModel:cacheSlideModel pointIndex:key];
  280. }
  281. break;
  282. case CENTRETYPE:
  283. {
  284. [HPSlideSegmentView layoutWithView:self.slideCentre cacheSlideModel:cacheSlideModel pointIndex:key];
  285. }
  286. break;
  287. case RIGHTTYPE:
  288. {
  289. [HPSlideSegmentView layoutWithView:self.slideRight cacheSlideModel:cacheSlideModel pointIndex:key];
  290. }
  291. break;
  292. default:
  293. break;
  294. }
  295. }
  296. -(void)hp_updateWihtLayotu{
  297. [self currenSlideScrollView];
  298. }
  299. #pragma mark - 监听
  300. -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
  301. UIScrollView *scrollView = (UIScrollView *)object;
  302. if (self.centreScrollerView == scrollView && [@"contentOffset" isEqualToString:keyPath] && _privateChangeCahePoint != scrollView.contentOffset.y) {
  303. if ([self.upDelegate respondsToSelector:@selector(hp_currentMainSlideScrollView:)]) {
  304. _privateChangeCahePoint = scrollView.contentOffset.y;
  305. [self.upDelegate hp_currentMainSlideScrollView:self.centreScrollerView];
  306. }
  307. }
  308. }
  309. -(void)getControllerWithScrollView:(HPSlideModel *)slideModel{
  310. for (id object in [slideModel.showViewController.view subviews]) {
  311. if ([object isKindOfClass:[UIScrollView class]]) {
  312. UIScrollView * scrollView = (UIScrollView *)object;
  313. if (scrollView.contentSize.height > slideModel.showViewController.view.height) {
  314. slideModel.mainSlideScrollView = scrollView;
  315. break;
  316. }
  317. }
  318. }
  319. }
  320. -(void)setCacheMaxCount:(NSUInteger )cacheMaxCount
  321. {
  322. _cacheMaxCount=cacheMaxCount;
  323. self.cacheListMange.cacheListMax=cacheMaxCount;
  324. }
  325. -(HPSlideModel *)slideLeft
  326. {
  327. if (_slideLeft==nil) {
  328. _slideLeft=[[HPSlideModel alloc] init];
  329. _slideLeft.frame=CGRectMake(0, 0, self.width, self.height);
  330. }
  331. return _slideLeft;
  332. }
  333. -(HPSlideModel *)slideCentre
  334. {
  335. if (_slideCentre==nil) {
  336. _slideCentre=[[HPSlideModel alloc] init];
  337. _slideCentre.frame=CGRectMake(0, 0, self.width, self.height);
  338. }
  339. return _slideCentre;
  340. }
  341. -(HPSlideModel *)slideRight
  342. {
  343. if (_slideRight==nil) {
  344. _slideRight=[[HPSlideModel alloc] init];
  345. _slideRight.frame=CGRectMake(0, 0, self.width, self.height);
  346. }
  347. return _slideRight;
  348. }
  349. -(HPCacheListManage *)cacheListMange
  350. {
  351. if (_cacheListMange==nil) {
  352. _cacheListMange=[[HPCacheListManage alloc] init];
  353. _cacheListMange.delegate=self;
  354. }
  355. return _cacheListMange;
  356. }
  357. //
  358. -(HPKVOMange *)kvoMange
  359. {
  360. if (_kvoMange==nil) {
  361. _kvoMange=[[HPKVOMange alloc] init];
  362. }
  363. return _kvoMange;
  364. }
  365. //
  366. -(HPScrollView *)viewContrllerScrollerView
  367. {
  368. if (_viewContrllerScrollerView==nil) {
  369. _viewContrllerScrollerView=[[HPScrollView alloc] init];
  370. _viewContrllerScrollerView.gestrueType = HPScrollView_Filter_GestureCell;
  371. _viewContrllerScrollerView.pagingEnabled=YES;
  372. _viewContrllerScrollerView.delegate=self;
  373. _viewContrllerScrollerView.bounces=NO;
  374. _viewContrllerScrollerView.backgroundColor=[UIColor clearColor];
  375. _viewContrllerScrollerView.showsVerticalScrollIndicator=NO;
  376. _viewContrllerScrollerView.showsHorizontalScrollIndicator=NO;
  377. }
  378. return _viewContrllerScrollerView;
  379. }
  380. @end
  381. @implementation HPSlideModel
  382. -(id)cacheWithClass:(Class)className initAction:(InitWithActionBlock)actionBlock
  383. {
  384. if (className==nil) {
  385. return nil;
  386. }
  387. id cacheObj=self.showViewController;
  388. if (cacheObj==nil) {
  389. cacheObj=[[className alloc] init];
  390. if (actionBlock!=nil) {
  391. actionBlock(self);
  392. }
  393. }
  394. return cacheObj;
  395. }
  396. -(id)cacheWithStoryboard:(UIStoryboard *)storyboard identifier:(NSString *)identifier
  397. {
  398. if (storyboard==nil || identifier==nil) {
  399. return nil;
  400. }
  401. id cacheObj=self.showViewController;
  402. if (cacheObj==nil) {
  403. cacheObj=[storyboard instantiateViewControllerWithIdentifier:identifier];
  404. }
  405. return cacheObj;
  406. }
  407. //-(void)showViewController:(UIViewController *)showViewController pointIndex:(NSUInteger)index
  408. //{
  409. // if (showViewController==nil) {
  410. // return;
  411. // }
  412. //
  413. // self.showViewController=showViewController;
  414. // showViewController.view.frame=CGRectMake(0, 0, self.width, self.height);
  415. // self.frame = CGRectMake(index * self.width, 0, self.width, self.height);
  416. // [self addSubview:showViewController.view];
  417. //}
  418. @end