WMZPageController.m 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. //
  2. // WMZPageController.m
  3. // WMZPageController
  4. //
  5. // Created by wmz on 2019/9/22.
  6. // Copyright © 2019 wmz. All rights reserved.
  7. //
  8. #import "WMZPageController.h"
  9. @interface WMZPageController()
  10. {
  11. BOOL hadWillDisappeal;
  12. NSInteger footerViewIndex;
  13. CGFloat sonChildVCHeight;
  14. CGFloat sonChildVCY;
  15. }
  16. //当前子控制器中的滚动视图
  17. @property(nonatomic,strong)UIScrollView *currentScroll;
  18. //当前子控制器中需要固定的底部视图
  19. @property(nonatomic,strong)UIView *currentFootView;
  20. //头部视图
  21. @property(nonatomic,strong)UIView *headView;
  22. //头部视图菜单栏底部的占位视图(如有需要)
  23. @property(nonatomic,strong)UIView *head_MenuView;
  24. //视图消失时候的导航栏透明度 有透明度变化的时候
  25. @property(nonatomic,strong)NSNumber *lastAlpah;
  26. //视图出现时候的导航栏透明度
  27. @property(nonatomic,strong)NSNumber *enterAlpah;
  28. //底部tableView是否可以滚动
  29. @property (nonatomic, assign) BOOL canScroll;
  30. //onTableView是否可以滚动
  31. @property (nonatomic, assign) BOOL sonCanScroll;
  32. //到达顶部
  33. @property (nonatomic, assign) BOOL scrolTotop;
  34. //到达底部
  35. @property (nonatomic, assign) BOOL scrolToBottom;
  36. @property (nonatomic, strong) UIView *naviBarBackGround;
  37. //headHeight
  38. @property (nonatomic, assign) CGFloat headHeight;
  39. @end
  40. @implementation WMZPageController
  41. //更新
  42. - (void)updatePageController{
  43. [self.upSc removeFromSuperview];
  44. [self.downSc removeFromSuperview];
  45. self.downSc = [[WMZPageScroller alloc]initWithFrame:CGRectMake(0, 0, PageVCWidth, PageVCHeight) style:UITableViewStyleGrouped];
  46. [self.sonChildScrollerViewDic removeAllObjects];
  47. [self.sonChildFooterViewDic removeAllObjects];
  48. [self.rectArr removeAllObjects];
  49. footerViewIndex = -1;
  50. for (UIViewController *VC in self.childViewControllers) {
  51. [VC willMoveToParentViewController:nil];
  52. [VC.view removeFromSuperview];
  53. [VC removeFromParentViewController];
  54. }
  55. [self setParam];
  56. [self UI];
  57. }
  58. //更新头部
  59. - (void)updateHeadView{
  60. [self setUpHead];
  61. }
  62. /*
  63. *底部手动滚动 传入CGPointZero则为吸顶临界点
  64. */
  65. - (void)downScrollViewSetOffset:(CGPoint)point animated:(BOOL)animat;{
  66. if (CGPointEqualToPoint(point, CGPointZero)) {
  67. //顶点
  68. int topOffset = self.downSc.contentSize.height - self.downSc.frame.size.height;
  69. if (!self.parentViewController) {
  70. topOffset -=PageVCStatusBarHeight;
  71. }else{
  72. if (!self.param.wFromNavi) {
  73. topOffset -=PageVCNavBarHeight;
  74. }
  75. }
  76. point = CGPointMake(self.downSc.contentOffset.x, topOffset);
  77. }
  78. [self.downSc setContentOffset:point animated:animat];
  79. }
  80. - (void)viewDidLoad{
  81. self.view.backgroundColor = [UIColor whiteColor];
  82. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  83. [self setParam];
  84. [self UI];
  85. if (self.naviBarBackGround&&self.param.wNaviColor) {
  86. self.naviBarBackGround.backgroundColor = self.param.wNaviColor;
  87. }
  88. });
  89. }
  90. - (void)viewWillDisappear:(BOOL)animated{
  91. [super viewWillDisappear:animated];
  92. if (self.naviBarBackGround&&self.param.wNaviAlpha) {
  93. self.lastAlpah = @(self.naviBarBackGround.alpha);
  94. }
  95. hadWillDisappeal = YES;
  96. }
  97. - (void)viewDidDisappear:(BOOL)animated{
  98. [super viewDidDisappear:animated];
  99. if (self.naviBarBackGround&&self.param.wNaviAlpha) {
  100. self.lastAlpah = @(self.naviBarBackGround.alpha);
  101. self.naviBarBackGround.alpha = self.enterAlpah?self.enterAlpah.floatValue:1;
  102. }
  103. }
  104. - (void)viewWillAppear:(BOOL)animated{
  105. [super viewWillAppear:animated];
  106. hadWillDisappeal = NO;
  107. if (self.navigationController&&self.param.wNaviAlpha) {
  108. self.naviBarBackGround.alpha = 0;
  109. if (self.naviBarBackGround&&self.lastAlpah){
  110. self.naviBarBackGround.alpha = self.lastAlpah.floatValue;
  111. return;
  112. }
  113. if (self.param.wNaviAlphaAll) {
  114. self.naviBarBackGround = self.navigationController.navigationBar;
  115. self.enterAlpah = @(self.naviBarBackGround.alpha);
  116. [self.naviBarBackGround setAlpha:0];
  117. }else{
  118. NSMutableArray *loop= [NSMutableArray new];
  119. [loop addObject:[self.navigationController.navigationBar subviews]];
  120. while (loop.count) {
  121. NSArray *arr = loop.lastObject;
  122. [loop removeLastObject];
  123. for (NSInteger i = arr.count - 1; i >= 0; i--) {
  124. UIView *view = arr[i];
  125. [loop addObject:view.subviews];
  126. if ([[UIDevice currentDevice].systemVersion intValue]>=12&&[[UIDevice currentDevice].systemVersion intValue]<13){
  127. if ([NSStringFromClass([view class]) isEqualToString:@"UIVisualEffectView"]) {
  128. self.naviBarBackGround = view;
  129. self.enterAlpah = @(self.naviBarBackGround.alpha);
  130. [self.naviBarBackGround setAlpha:0];
  131. break;
  132. }
  133. }else{
  134. if ([NSStringFromClass([view class]) isEqualToString:@"_UIBarBackground"]||[NSStringFromClass([view class]) isEqualToString:@"_UINavigationBarBackground"]) {
  135. self.naviBarBackGround = view;
  136. self.enterAlpah = @(self.naviBarBackGround.alpha);
  137. [self.naviBarBackGround setAlpha:0];
  138. break;
  139. }
  140. }
  141. }
  142. }
  143. }
  144. }
  145. }
  146. - (void)setParam{
  147. if (self.param.wInsertHeadAndMenuBg) {
  148. self.head_MenuView = [UIView new];
  149. self.param.wInsertHeadAndMenuBg(self.head_MenuView);
  150. }
  151. if (self.param.wMenuAnimal == PageTitleMenuAiQY) {
  152. if (!self.param.wMenuIndicatorWidth) {
  153. self.param.wMenuIndicatorWidth = 20;
  154. }
  155. }
  156. if (self.param.wMenuAnimal == PageTitleMenuNone||
  157. self.param.wMenuAnimal == PageTitleMenuCircle||
  158. self.param.wMenuAnimal == PageTitleMenuPDD) {
  159. self.param.wMenuAnimalTitleBig = NO;
  160. self.param.wMenuAnimalTitleGradient = NO;
  161. }
  162. if (self.param.wMenuAnimal == PageTitleMenuYouKu) {
  163. self.param.wMenuIndicatorWidth = 6;
  164. self.param.wMenuIndicatorHeight = 3;
  165. }
  166. if (self.param.wMenuAnimal == PageTitleMenuCircle) {
  167. if (CGColorEqualToColor(self.param.wMenuIndicatorColor.CGColor, PageColor(0xE5193E).CGColor)) {
  168. self.param.wMenuIndicatorColor = PageColor(0xe1f9fe);
  169. }
  170. if (CGColorEqualToColor(self.param.wMenuTitleSelectColor.CGColor, PageColor(0xE5193E).CGColor)) {
  171. self.param.wMenuTitleSelectColor = PageColor(0x00baf9);
  172. }
  173. }
  174. if (self.param.wMenuPosition == PageMenuPositionNavi) {
  175. if (CGColorEqualToColor(self.param.wMenuBgColor.CGColor, PageColor(0xffffff).CGColor)) {
  176. self.param.wMenuBgColor = [UIColor clearColor];
  177. }
  178. }
  179. }
  180. - (void)UI{
  181. self.cache = [NSCache new];
  182. self.cache.countLimit = 30;
  183. footerViewIndex = -1;
  184. CGFloat headY = 0;
  185. CGFloat tabbarHeight = 0;
  186. CGFloat statusBarHeight = 0;
  187. if (self.presentingViewController) {
  188. if (!self.navigationController) {
  189. statusBarHeight = PageVCStatusBarHeight;
  190. }
  191. } else if (self.tabBarController) {
  192. if (!self.tabBarController.tabBar.translucent) {
  193. tabbarHeight = 0;
  194. }else{
  195. tabbarHeight = PageVCTabBarHeight;
  196. }
  197. } else if (self.navigationController){
  198. headY = (!self.param.wFromNavi&&
  199. self.param.wMenuPosition != PageMenuPositionNavi&&
  200. self.param.wMenuPosition != PageMenuPositionBottom)?0:
  201. (!self.navigationController.navigationBar.translucent?0:PageVCNavBarHeight);
  202. }
  203. if (self.parentViewController) {
  204. if ([self.parentViewController isKindOfClass:[UINavigationController class]]) {
  205. UINavigationController *naPar = (UINavigationController*)self.parentViewController;
  206. headY = (!self.param.wFromNavi&&
  207. self.param.wMenuPosition != PageMenuPositionNavi&&
  208. self.param.wMenuPosition != PageMenuPositionBottom)?0:
  209. (!naPar.navigationBar.translucent?0:PageVCNavBarHeight);
  210. if (self.parentViewController.tabBarController) {
  211. if (!self.parentViewController.tabBarController.tabBar.translucent) {
  212. tabbarHeight = 0;
  213. }else{
  214. tabbarHeight = PageVCTabBarHeight;
  215. }
  216. }
  217. }else if ([self.parentViewController isKindOfClass:[UITabBarController class]]) {
  218. UITabBarController *ta = (UITabBarController*)self.parentViewController;
  219. if (!ta.tabBar.translucent) {
  220. tabbarHeight = 0;
  221. }else{
  222. tabbarHeight = PageVCTabBarHeight;
  223. }
  224. if (self.parentViewController.navigationController) {
  225. headY = (!self.param.wFromNavi&&
  226. self.param.wMenuPosition != PageMenuPositionNavi&&
  227. self.param.wMenuPosition != PageMenuPositionBottom)?0:(!self.parentViewController.navigationController.navigationBar.translucent?0:PageVCNavBarHeight);
  228. }else if(self.parentViewController.presentingViewController){
  229. statusBarHeight = PageVCStatusBarHeight;
  230. }
  231. }else if ([self.parentViewController isKindOfClass:[WMZPageController class]]) {
  232. headY = 0;
  233. tabbarHeight = 0;
  234. statusBarHeight = 0;
  235. }
  236. }
  237. if (self.hidesBottomBarWhenPushed&&tabbarHeight>=PageVCTabBarHeight) {
  238. tabbarHeight -= PageVCTabBarHeight;
  239. }
  240. //全屏
  241. if (self.navigationController) {
  242. for (UIGestureRecognizer *gestureRecognizer in self.downSc.gestureRecognizers) {
  243. [gestureRecognizer requireGestureRecognizerToFail:self.navigationController.interactivePopGestureRecognizer];
  244. }
  245. }
  246. if (@available(iOS 11.0, *)) {
  247. self.downSc.estimatedRowHeight = 0.01;
  248. self.downSc.estimatedSectionFooterHeight = 0.01;
  249. self.downSc.estimatedSectionHeaderHeight = 0.01;
  250. self.downSc.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  251. }else{
  252. self.downSc.estimatedRowHeight = 0;
  253. }
  254. self.downSc.sectionHeaderHeight = 0.01;
  255. self.downSc.sectionFooterHeight = 0.01;
  256. self.downSc.delegate = self;
  257. self.downSc.bounces = self.param.wBounces;
  258. self.downSc.frame = CGRectMake(0, headY, self.view.frame.size.width, self.view.frame.size.height-headY-tabbarHeight);
  259. [self.view addSubview:self.downSc];
  260. //滚动和菜单视图
  261. self.upSc = [[WMZPageLoopView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height) param:self.param];
  262. self.upSc.loopDelegate = self;
  263. self.downSc.tableFooterView = self.upSc;
  264. if (self.navigationController) {
  265. for (UIGestureRecognizer *gestureRecognizer in self.upSc.gestureRecognizers) {
  266. [gestureRecognizer requireGestureRecognizerToFail:self.navigationController.interactivePopGestureRecognizer];
  267. }
  268. }
  269. //底部
  270. sonChildVCY = 0;
  271. sonChildVCHeight = 0;
  272. CGFloat titleMenuhHeight = self.upSc.mainView.frame.size.height;
  273. if (self.param.wMenuPosition == PageMenuPositionNavi) {
  274. sonChildVCY = 0;
  275. sonChildVCHeight = self.downSc.frame.size.height;
  276. }else if (self.param.wMenuPosition == PageMenuPositionBottom) {
  277. sonChildVCY = 0;
  278. sonChildVCHeight = self.downSc.frame.size.height - titleMenuhHeight;
  279. }else{
  280. sonChildVCY = 0;
  281. sonChildVCHeight = self.downSc.frame.size.height - titleMenuhHeight;
  282. }
  283. if (self.param.wTopOffset) {
  284. sonChildVCHeight -= self.param.wTopOffset;
  285. }
  286. if (self.param.wMenuPosition == PageMenuPositionBottom){
  287. [self.upSc.dataView page_y:0];
  288. [self.upSc.dataView page_height:sonChildVCHeight];
  289. [self.upSc.mainView page_y:CGRectGetMaxY(self.upSc.dataView.frame)];
  290. [self.upSc page_height:CGRectGetMaxY(self.upSc.mainView.frame)];
  291. }else if (self.param.wMenuPosition == PageMenuPositionNavi && self.navigationController) {
  292. [self.upSc.mainView removeFromSuperview];
  293. [self.upSc.dataView page_y:0];
  294. [self.upSc.dataView page_height:sonChildVCHeight];
  295. [self.upSc page_height:CGRectGetMaxY(self.upSc.dataView.frame)];
  296. self.navigationItem.titleView = self.upSc.mainView;
  297. }else{
  298. [self.upSc.dataView page_y:CGRectGetMaxY(self.upSc.mainView.frame)];
  299. [self.upSc.dataView page_height:sonChildVCHeight];
  300. [self.upSc page_height:CGRectGetMaxY(self.upSc.dataView.frame)];
  301. }
  302. self.param.titleHeight = self.upSc.mainView.frame.size.height;
  303. self.downSc.menuTitleHeight = self.param.titleHeight;
  304. self.downSc.canScroll = [self canTopSuspension];
  305. self.downSc.scrollEnabled = [self canTopSuspension];
  306. self.downSc.wFromNavi = self.param.wFromNavi;
  307. if (self.param.wCustomMenuTitle) {
  308. self.param.wCustomMenuTitle(self.upSc.btnArr);
  309. }
  310. [self setUpHead];
  311. [self.upSc.btnArr enumerateObjectsUsingBlock:^(WMZPageNaviBtn* _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  312. if (idx == self.param.wMenuDefaultIndex) {
  313. self.upSc.first = YES;
  314. [obj sendActionsForControlEvents:UIControlEventTouchUpInside];
  315. *stop = YES;
  316. }
  317. }];
  318. self.canScroll = YES;
  319. self.scrolToBottom = YES;
  320. if (@available(iOS 11.0, *)) {
  321. [[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
  322. }else {
  323. self.automaticallyAdjustsScrollViewInsets = NO;
  324. }
  325. }
  326. - (void)setUpHead{
  327. //头部视图
  328. if(self.param.wMenuHeadView&&
  329. self.param.wMenuPosition != PageMenuPositionNavi&&
  330. self.param.wMenuPosition != PageMenuPositionBottom) {
  331. self.headView = self.param.wMenuHeadView();
  332. self.headView.frame = CGRectMake(self.headView.frame.origin.x, 0, self.headView.frame.size.width, self.headView.frame.size.height);
  333. self.downSc.tableHeaderView = self.headView;
  334. }else{
  335. self.downSc.tableHeaderView = [[UIView alloc]initWithFrame:CGRectMake( 0, 0,self.view.frame.size.width, 0.01)];
  336. }
  337. self.rectArr = [NSMutableArray new];
  338. for (int i = 0; i<self.param.wTitleArr.count; i++) {
  339. CGFloat height = [self canTopSuspension]?sonChildVCHeight :(sonChildVCHeight-self.headHeight);
  340. if ([self canTopSuspension]) {
  341. if (!self.parentViewController) {
  342. height -=PageVCStatusBarHeight;
  343. }else{
  344. if (self.navigationController) {
  345. if (!self.param.wFromNavi) {
  346. height -= (self.navigationController.navigationBar.translucent?PageVCNavBarHeight:0);
  347. }
  348. }else{
  349. height -= PageVCStatusBarHeight;
  350. }
  351. }
  352. }
  353. CGRect frame = CGRectMake(i * self.downSc.frame.size.width,
  354. [self canTopSuspension]?0:sonChildVCY,
  355. self.downSc.frame.size.width,
  356. height);
  357. [self.rectArr addObject:[NSValue valueWithCGRect:frame]];
  358. }
  359. //全景
  360. if (self.head_MenuView) {
  361. self.head_MenuView.frame = CGRectMake(0, self.headView?CGRectGetMinX(self.headView.frame):CGRectGetMinX(self.upSc.frame), self.upSc.frame.size.width, CGRectGetMaxY(self.upSc.frame)-self.upSc.dataView.frame.size.height);
  362. [self.downSc addSubview:self.head_MenuView];
  363. [self.downSc sendSubviewToBack:self.head_MenuView];
  364. self.upSc.mainView.backgroundColor = [UIColor clearColor];
  365. for (WMZPageNaviBtn *btn in self.upSc.btnArr) {
  366. btn.backgroundColor = [UIColor clearColor];
  367. }
  368. if (self.headView) {
  369. self.headView.backgroundColor = [UIColor clearColor];
  370. }
  371. }
  372. }
  373. //底部滚动
  374. - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
  375. if (scrollView!=self.downSc) return;
  376. if (![self canTopSuspension]) return;
  377. //偏移量
  378. float yOffset = scrollView.contentOffset.y;
  379. //顶点
  380. int topOffset = scrollView.contentSize.height - scrollView.frame.size.height;
  381. if (!self.parentViewController||!self.navigationController) {
  382. topOffset -=PageVCStatusBarHeight;
  383. }else{
  384. UINavigationController *naPar = (UINavigationController*)self.parentViewController;
  385. if (!self.param.wFromNavi) {
  386. if (naPar.navigationBar.translucent) {
  387. topOffset -=PageVCNavBarHeight;
  388. }
  389. }
  390. }
  391. //外部传入 修改此属性即可
  392. if (self.param.wTopOffset) {
  393. topOffset += self.param.wTopOffset;
  394. }
  395. if (yOffset<=0) {
  396. self.scrolToBottom = YES;
  397. }else{
  398. if (yOffset >= topOffset) {
  399. scrollView.contentOffset = CGPointMake(self.downSc.contentOffset.x, topOffset);
  400. self.scrolTotop = YES;
  401. }else{
  402. self.scrolTotop = NO;
  403. }
  404. self.scrolToBottom = NO;
  405. }
  406. if (self.scrolTotop) {
  407. self.sonCanScroll = YES;
  408. if (self.currentScroll.contentSize.height<=self.currentScroll.frame.size.height) {
  409. self.canScroll = YES;
  410. }else{
  411. self.canScroll = NO;
  412. }
  413. }else {
  414. if (!self.canScroll) {
  415. scrollView.contentOffset = CGPointMake(0, topOffset);
  416. }else {
  417. self.sonCanScroll = NO;
  418. }
  419. }
  420. CGFloat delta = scrollView.contentOffset.y/topOffset;
  421. if (delta>1) {
  422. delta = 1;
  423. }else if (delta < 0){
  424. delta = 0;
  425. }
  426. if (self.param.wNaviAlpha) {
  427. if (self.navigationController&&self.naviBarBackGround) {
  428. self.naviBarBackGround.alpha = delta;
  429. }
  430. if (self.headView) {
  431. if (delta == 1) {
  432. self.headView.alpha = 0;
  433. }else{
  434. self.headView.alpha = 1;
  435. }
  436. }
  437. }
  438. if (self.param.wEventChildVCDidSroll) {
  439. self.param.wEventChildVCDidSroll(self,self.downSc.contentOffset, self.downSc.contentOffset, self.downSc);
  440. }
  441. //防止第一次加载不成功
  442. if (self.currentFootView&&
  443. self.currentFootView.frame.origin.y!=
  444. self.footViewOrginY) {
  445. [self.currentFootView page_y:self.footViewOrginY];
  446. }
  447. }
  448. //设置悬浮
  449. - (void)setUpSuspension:(UIViewController*)newVC index:(NSInteger)index end:(BOOL)end{
  450. if (![self canTopSuspension]) return;
  451. if ([newVC conformsToProtocol:@protocol(WMZPageProtocol)]) {
  452. UIScrollView *view = nil;
  453. if ([newVC respondsToSelector:@selector(getMyTableView)]) {
  454. UIScrollView *tmpView = [newVC performSelector:@selector(getMyTableView)];
  455. if (tmpView&&[tmpView isKindOfClass:[UIScrollView class]]) {
  456. view = tmpView;
  457. }
  458. }else if([newVC respondsToSelector:@selector(getMyScrollView)]){
  459. UIScrollView *tmpView = [newVC performSelector:@selector(getMyScrollView)];
  460. if (tmpView&&[tmpView isKindOfClass:[UIScrollView class]]) {
  461. view = tmpView;
  462. }
  463. }
  464. if (view) {
  465. self.currentScroll = view;
  466. [self.sonChildScrollerViewDic setObject:view forKey:@(index)];
  467. if (self.scrolToBottom) {
  468. view.contentOffset = CGPointMake(view.contentOffset.x,0);
  469. }
  470. [self.currentScroll pageAddObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
  471. }
  472. if ([newVC respondsToSelector:@selector(fixFooterView)]) {
  473. UIView *tmpView = [newVC performSelector:@selector(fixFooterView)];
  474. [self.sonChildFooterViewDic setObject:view forKey:@(index)];
  475. self.currentFootView = tmpView;
  476. [self.view addSubview:self.currentFootView];
  477. self.currentFootView.hidden = NO;
  478. footerViewIndex = index;
  479. [self.currentFootView page_y:self.footViewOrginY];
  480. }else{
  481. if (self.currentFootView&&
  482. end) {
  483. if (!self.param.wFixFirst) {
  484. self.currentFootView.hidden = YES;
  485. }
  486. }
  487. }
  488. }else{
  489. self.currentScroll = nil;
  490. self.currentFootView = nil;
  491. }
  492. }
  493. //底部左滑滚动
  494. - (void)pageWithScrollView:(UIScrollView*)scrollView left:(BOOL)left{
  495. int offset = (int)scrollView.contentOffset.x%(int)self.upSc.frame.size.width;
  496. NSInteger index = floor(scrollView.contentOffset.x/self.upSc.frame.size.width);
  497. if (self.currentFootView) {
  498. int x = 0;
  499. CGFloat width = self.footViewSizeWidth;
  500. if (left) {
  501. if (scrollView.contentOffset.x>(self.upSc.frame.size.width*footerViewIndex)) {
  502. x = 0;
  503. width -= offset;
  504. }else{
  505. x = (int)self.upSc.frame.size.width - offset;
  506. }
  507. }else{
  508. if (scrollView.contentOffset.x>(self.upSc.frame.size.width*footerViewIndex)) {
  509. x = 0;
  510. width -= offset;
  511. }else{
  512. x = (int)self.upSc.frame.size.width - offset;
  513. }
  514. }
  515. if (offset == 0 && [self.sonChildFooterViewDic objectForKey:@(index)]) {
  516. x = self.footViewOrginX;
  517. }
  518. if (!self.param.wFixFirst) {
  519. [self.currentFootView page_x: x];
  520. [self.currentFootView page_width:width];
  521. }
  522. }
  523. }
  524. //选中按钮
  525. - (void)selectBtnWithIndex:(NSInteger)index{
  526. if (self.currentFootView) {
  527. if (!self.param.wFixFirst) {
  528. [self.currentFootView page_x:self.footViewOrginX];
  529. }
  530. }
  531. }
  532. //监听子控制器中的滚动视图
  533. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
  534. if ([keyPath isEqualToString:@"contentOffset"]) {
  535. if (![self canTopSuspension]) return;
  536. if (self.currentScroll!=object) return;
  537. if (hadWillDisappeal) return;
  538. CGPoint newH = [[change objectForKey:@"new"] CGPointValue];
  539. CGPoint newOld = [[change objectForKey:@"old"] CGPointValue];
  540. if (newH.y==newOld.y) return;
  541. if (!self.sonCanScroll&&!self.scrolToBottom) {
  542. self.currentScroll.contentOffset = CGPointZero;
  543. self.downSc.showsVerticalScrollIndicator = YES;
  544. self.currentScroll.showsVerticalScrollIndicator = NO;
  545. }else{
  546. self.downSc.showsVerticalScrollIndicator = NO;
  547. self.currentScroll.showsVerticalScrollIndicator = YES;
  548. }
  549. if ((int)newH.y<=0) {
  550. self.canScroll = YES;
  551. if (self.param.wBounces) {
  552. self.currentScroll.contentOffset = CGPointZero;
  553. }
  554. }
  555. }
  556. }
  557. - (BOOL)canTopSuspension{
  558. if (!self.param.wTopSuspension
  559. ||self.param.wMenuPosition == PageMenuPositionBottom
  560. ||self.param.wMenuPosition == PageMenuPositionNavi){
  561. return NO;
  562. }
  563. return YES;
  564. }
  565. /*
  566. *手动调用菜单到第index个
  567. */
  568. - (void)selectMenuWithIndex:(NSInteger)index{
  569. [self.upSc.btnArr enumerateObjectsUsingBlock:^(WMZPageNaviBtn* _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  570. if (idx == index) {
  571. [obj sendActionsForControlEvents:UIControlEventTouchUpInside];
  572. *stop = YES;
  573. }
  574. }];
  575. }
  576. - (NSMutableArray *)rectArr{
  577. if (!_rectArr) {
  578. _rectArr = [NSMutableArray new];
  579. }
  580. return _rectArr;
  581. }
  582. - (NSMutableDictionary *)sonChildScrollerViewDic{
  583. if (!_sonChildScrollerViewDic) {
  584. _sonChildScrollerViewDic = [NSMutableDictionary new];
  585. }
  586. return _sonChildScrollerViewDic;
  587. }
  588. - (NSMutableDictionary *)sonChildFooterViewDic{
  589. if (!_sonChildFooterViewDic) {
  590. _sonChildFooterViewDic = [NSMutableDictionary new];
  591. }
  592. return _sonChildFooterViewDic;
  593. }
  594. - (WMZPageScroller *)downSc{
  595. if (!_downSc) {
  596. _downSc = [[WMZPageScroller alloc]initWithFrame:CGRectMake(0, 0, PageVCWidth, PageVCHeight) style:UITableViewStyleGrouped];
  597. }
  598. return _downSc;
  599. }
  600. - (CGFloat)footViewOrginY{
  601. if (!_footViewOrginY) {
  602. _footViewOrginY = CGRectGetMaxY(self.downSc.frame)-self.currentFootView.frame.size.height;
  603. }
  604. return _footViewOrginY;
  605. }
  606. - (CGFloat)headHeight{
  607. _headHeight = self.headView.frame.size.height;
  608. return _headHeight;
  609. }
  610. - (CGFloat)footViewSizeWidth{
  611. if (!_footViewSizeWidth) {
  612. _footViewSizeWidth = self.upSc.frame.size.width;
  613. }
  614. return _footViewSizeWidth;
  615. }
  616. - (void)didReceiveMemoryWarning{
  617. [super didReceiveMemoryWarning];
  618. [self.cache removeAllObjects];
  619. [self.sonChildScrollerViewDic removeAllObjects];
  620. }
  621. - (void)dealloc{
  622. [self.sonChildScrollerViewDic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
  623. [obj removeAllObserverdKeyPath:self withKey:@"contentOffset"];
  624. }];
  625. }
  626. @end