dkahgld

BaseSlideViewController.m 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. //
  2. // BaseSlideViewController.m
  3. // SlideViewController
  4. //
  5. // Created by 周智勇 on 17/2/27.
  6. // Copyright © 2017年 周智勇. All rights reserved.
  7. //
  8. #import "BaseSlideViewController.h"
  9. #define ScreenW [UIScreen mainScreen].bounds.size.width
  10. #define ScreenH [UIScreen mainScreen].bounds.size.height
  11. #define RGBColor(r,g,b) RGBAColor(r,g,b,1.0)
  12. #define RGBAColor(r,g,b,a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:a]
  13. static CGFloat const titleH = 41;/** 文字高度 */
  14. static CGFloat const MaxScale = 1.1;/** 选中文字放大 */
  15. @interface BaseSlideViewController ()<UIScrollViewDelegate>
  16. /** 控制器scrollView */
  17. @property (nonatomic, strong) UIScrollView *contentScrollView;
  18. /** 标签文字 */
  19. //@property (nonatomic ,strong) NSArray * titlesArr;
  20. /** 标签按钮 */
  21. @property (nonatomic, strong) NSMutableArray *buttons;
  22. /** 选中的按钮 */
  23. @property (nonatomic ,strong) UIButton * selectedBtn;
  24. /** 选中的按钮背景图 */
  25. @property (nonatomic ,strong) UIImageView * imageBackView;
  26. /** 选中的按钮下边的线条 */
  27. @property (nonatomic, strong)UIView * lineView;
  28. /** 文字scrollView */
  29. @property (nonatomic, strong) UIScrollView *titleScrollView;
  30. @end
  31. @implementation BaseSlideViewController
  32. #pragma mark lazy loading
  33. - (NSMutableArray *)buttons
  34. {
  35. if (!_buttons)
  36. {
  37. _buttons = [NSMutableArray array];
  38. }
  39. return _buttons;
  40. }
  41. - (void)updateSuperTitleAry{
  42. //外部更新标签的时候,先要移除之前添加的控制器和视图
  43. // [self.view.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  44. // [obj removeFromSuperview];
  45. // }];
  46. [self.childViewControllers enumerateObjectsUsingBlock:^(__kindof UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  47. [obj removeFromParentViewController];
  48. }];
  49. [self addChildViewController]; /** 添加子控制器视图 */
  50. [self setTitleScrollView]; /** 添加文字标签 */
  51. [self setContentScrollView]; /** 添加scrollView */
  52. [self setupTitle]; /** 设置标签按钮 文字 背景图 */
  53. self.automaticallyAdjustsScrollViewInsets = NO;
  54. self.contentScrollView.contentSize = CGSizeMake(self.titlesArr.count * ScreenW, 0);
  55. self.contentScrollView.pagingEnabled = YES;
  56. self.contentScrollView.showsHorizontalScrollIndicator = NO;
  57. self.contentScrollView.delegate = self;
  58. self.navBar.hidden=NO;
  59. self.navigationController.navigationBar.hidden=NO;
  60. }
  61. - (void)viewDidLoad {
  62. [super viewDidLoad];
  63. self.view.backgroundColor = [UIColor whiteColor];
  64. }
  65. #pragma mark - PRIVATE
  66. -(void)addChildViewController{
  67. for (int i = 0; i<self.titlesArr.count; i++) {
  68. //添加子类。子类一定要重写该方法!具体添加哪个视图,外部自己处理
  69. }
  70. }
  71. -(void)setTitleScrollView{
  72. CGRect rect = CGRectMake(0, NavBarHeight, ScreenW, titleH);
  73. self.titleScrollView = [[UIScrollView alloc] initWithFrame:rect];
  74. [self.view addSubview:self.titleScrollView];
  75. }
  76. -(void)setContentScrollView{
  77. CGFloat y = CGRectGetMaxY(self.titleScrollView.frame);
  78. CGRect rect = CGRectMake(0, y, ScreenW, ScreenH - titleH);
  79. self.contentScrollView = [[UIScrollView alloc] initWithFrame:rect];
  80. [self.view addSubview:self.contentScrollView];
  81. }
  82. -(void)setupTitle{
  83. NSUInteger count = self.childViewControllers.count;
  84. CGFloat x = 0;
  85. CGFloat w = ScreenW/4;
  86. if (w < 80) {
  87. w= 80;
  88. }
  89. CGFloat h = titleH;
  90. self.imageBackView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 5, w, titleH-10)];
  91. self.imageBackView.image = [UIImage imageNamed:@"b1"];
  92. self.imageBackView.backgroundColor = [UIColor whiteColor];
  93. self.imageBackView.userInteractionEnabled = YES;
  94. [self.titleScrollView addSubview:self.imageBackView];
  95. for (int i = 0; i < count; i++)
  96. {
  97. UIViewController *vc = self.childViewControllers[i];
  98. x = i * w;
  99. CGRect rect = CGRectMake(x, 0, w, h);
  100. UIButton *btn = [[UIButton alloc] initWithFrame:rect];
  101. btn.tag = i;
  102. [btn setTitle:vc.title forState:UIControlStateNormal];
  103. [btn setTitleColor:[UIColor YHColorWithHex:0x5B5B5B] forState:UIControlStateNormal];
  104. btn.titleLabel.font = [UIFont systemFontOfSize:14];
  105. [btn addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchDown];
  106. [self.buttons addObject:btn];
  107. [self.titleScrollView addSubview:btn];
  108. if (i == 0){
  109. [self click:btn];
  110. }
  111. }
  112. self.titleScrollView.contentSize = CGSizeMake(count * w, 0);
  113. self.titleScrollView.showsHorizontalScrollIndicator = NO;
  114. //增加下边的下划线(视具体情况可省略)
  115. UIView * covertView = [[UIView alloc] initWithFrame:CGRectMake(0, titleH - 1, self.titleScrollView.contentSize.width, 1)];
  116. [self.titleScrollView addSubview:covertView];
  117. self.lineView = [[UIView alloc] initWithFrame:CGRectMake(w/2-15, titleH - 2, 31, 2)];
  118. // if (self.titleScrollView.contentSize.width/self.titlesArr.count < 80) {
  119. // self.lineView = [[UIView alloc] initWithFrame:CGRectMake(0, titleH - 2, 80, 2)];
  120. // }else{
  121. // self.lineView = [[UIView alloc] initWithFrame:CGRectMake(0, titleH - 2, self.titleScrollView.contentSize.width/self.titlesArr.count, 2)];
  122. // }
  123. self.lineView.backgroundColor = [UIColor YHColorWithHex:0xFF7E00];
  124. [self.titleScrollView addSubview:self.lineView];
  125. //中间竖线
  126. for (int i = 0; i < self.titlesArr.count; i++) {
  127. UIView * midLineView = [[UIView alloc] initWithFrame:CGRectMake(self.titleScrollView.contentSize.width/self.titlesArr.count * i, 7, 0.5, 30)];
  128. midLineView.backgroundColor = RGBColor(246, 246, 246);
  129. [self.titleScrollView addSubview:midLineView];
  130. }
  131. }
  132. -(void)click:(UIButton *)sender{
  133. [self selectTitleBtn:sender];
  134. NSInteger i = sender.tag;
  135. CGFloat x = i *ScreenW;
  136. self.contentScrollView.contentOffset = CGPointMake(x, 0);
  137. [self setUpOneChildController:i];
  138. }
  139. -(void)selectTitleBtn:(UIButton *)btn{
  140. [self.selectedBtn setTitleColor:[UIColor YHColorWithHex:0x5B5B5B] forState:UIControlStateNormal];
  141. self.selectedBtn.transform = CGAffineTransformIdentity;
  142. [btn setTitleColor:[UIColor YHColorWithHex:0xFF7E00] forState:UIControlStateNormal];
  143. btn.transform = CGAffineTransformMakeScale(MaxScale, MaxScale);
  144. self.selectedBtn = btn;
  145. [self setupTitleCenter:btn];
  146. }
  147. -(void)setupTitleCenter:(UIButton *)sender
  148. {
  149. if (self.titleScrollView.contentSize.width <= ScreenW) {
  150. return;
  151. }
  152. //以上这一句代码保证数量较少时不会产生异常的偏移!!!!!!!!!
  153. CGFloat offset = sender.center.x - ScreenW * 0.5;
  154. if (offset < 0) {
  155. offset = 0;
  156. }
  157. CGFloat maxOffset = self.titleScrollView.contentSize.width - ScreenW;
  158. if (offset > maxOffset) {
  159. offset = maxOffset;
  160. }
  161. [self.titleScrollView setContentOffset:CGPointMake(offset, 0) animated:YES];
  162. }
  163. -(void)setUpCurrentChildController:(NSInteger)index
  164. {
  165. }
  166. -(void)setUpOneChildController:(NSInteger)index{
  167. CGFloat x = index * ScreenW;
  168. UIViewController *vc = self.childViewControllers[index];
  169. [self setUpCurrentChildController:index];
  170. if (vc.view.superview) {
  171. return;
  172. }
  173. vc.view.frame = CGRectMake(x, 0, ScreenW, ScreenH - self.contentScrollView.frame.origin.y);
  174. [self.contentScrollView addSubview:vc.view];
  175. }
  176. #pragma mark - UIScrollView delegate
  177. -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
  178. {
  179. NSInteger i = self.contentScrollView.contentOffset.x / ScreenW;
  180. [self selectTitleBtn:self.buttons[i]];
  181. [self setUpOneChildController:i];
  182. //如果需要检测视图滑动了,可以使用下边的通知。但是....
  183. // [[NSNotificationCenter defaultCenter] postNotificationName:@"ViewControllerSlided" object:nil userInfo:@{@"currentIndex":@(i)}];
  184. }
  185. -(void)scrollViewDidScroll:(UIScrollView *)scrollView
  186. {
  187. CGFloat offsetX = scrollView.contentOffset.x;
  188. NSInteger leftIndex = offsetX / ScreenW;
  189. NSInteger rightIdex = leftIndex + 1;
  190. UIButton *leftButton = self.buttons[leftIndex];
  191. UIButton *rightButton = nil;
  192. if (rightIdex < self.buttons.count) {
  193. rightButton = self.buttons[rightIdex];
  194. }
  195. CGFloat scaleR = offsetX / ScreenW - leftIndex;
  196. CGFloat scaleL = 1 - scaleR;
  197. CGFloat transScale = MaxScale - 1;
  198. self.imageBackView.transform = CGAffineTransformMakeTranslation((offsetX*(self.titleScrollView.contentSize.width / self.contentScrollView.contentSize.width)), 0);
  199. leftButton.transform = CGAffineTransformMakeScale(scaleL * transScale + 1, scaleL * transScale + 1);
  200. rightButton.transform = CGAffineTransformMakeScale(scaleR * transScale + 1, scaleR * transScale + 1);
  201. //修改下划线的frame
  202. self.lineView.transform = CGAffineTransformMakeTranslation((offsetX*(self.titleScrollView.contentSize.width / self.contentScrollView.contentSize.width)), 0);
  203. }
  204. @end