MLMSegmentHead.m 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. //
  2. // MLMSegmentHead.m
  3. // MLMSegmentPage
  4. //
  5. // Created by my on 16/11/4.
  6. // Copyright © 2016年 my. All rights reserved.
  7. //
  8. #import "MLMSegmentHead.h"
  9. #import "SegmentPageHead.h"
  10. #define SCROLL_WIDTH self.width
  11. #define SCROLL_HEIGHT (self.height - _bottomLineHeight)
  12. #define CURRENT_WIDTH(s) [titleWidthArray[s] floatValue] - 10
  13. static CGFloat arrow_H = 6;//箭头高
  14. static CGFloat arrow_W = 18;//箭头宽
  15. static CGFloat animation_time = .3;
  16. @interface MLMSegmentHead ()
  17. /*------------其他设置------------*/
  18. /**
  19. * MLMSegmentHeadStyle
  20. */
  21. @property (nonatomic, assign) MLMSegmentHeadStyle headStyle;
  22. /**
  23. * MLMSegmentHeadStyle
  24. */
  25. @property (nonatomic, assign) MLMSegmentLayoutStyle layoutStyle;
  26. @end
  27. @implementation MLMSegmentHead
  28. {
  29. NSMutableArray *titlesArray;///标题数组
  30. UIScrollView *titlesScroll;
  31. NSMutableArray *buttonArray;//按钮数组
  32. NSMutableArray *backImgArray;//背景图数组
  33. UIView *lineView;//下划线view
  34. CAShapeLayer *arrow_layer;//箭头layer
  35. UIView *slideView;//滑块View
  36. UIScrollView *slideScroll;
  37. UIView *bottomLineView;//分割线
  38. NSInteger currentIndex;//当前选中的按钮
  39. //在与外侧scroll关联时,动画结束之后将其设置为NO
  40. BOOL isSelected;//区分点击还是滑动
  41. //button宽度的数组,总宽度
  42. NSMutableArray *titleWidthArray;
  43. CGFloat sum_width;
  44. //用来判断向左向右
  45. CGFloat endScale;
  46. }
  47. #pragma mark - initMethod
  48. - (instancetype)initWithFrame:(CGRect)frame titles:(NSArray *)titles {
  49. return [self initWithFrame:frame titles:titles headStyle:SegmentHeadStyleDefault];
  50. }
  51. - (instancetype)initWithFrame:(CGRect)frame titles:(NSArray *)titles headStyle:(MLMSegmentHeadStyle)style {
  52. return [self initWithFrame:frame titles:titles headStyle:style layoutStyle:MLMSegmentLayoutDefault];
  53. }
  54. - (instancetype)initWithFrame:(CGRect)frame titles:(NSArray *)titles headStyle:(MLMSegmentHeadStyle)style layoutStyle:(MLMSegmentLayoutStyle)layout {
  55. if (self = [super initWithFrame:frame]) {
  56. _headStyle = style;
  57. _layoutStyle = layout;
  58. titlesArray = [titles mutableCopy];
  59. [self initCustom];
  60. }
  61. return self;
  62. }
  63. #pragma mark - custom init
  64. - (void)initCustom {
  65. _headColor = [UIColor whiteColor];
  66. _selectColor = [UIColor blackColor];
  67. _deSelectColor = [UIColor lightGrayColor];
  68. _moreButton_width = 0;
  69. buttonArray = [NSMutableArray array];
  70. backImgArray = [NSMutableArray array];
  71. _showIndex = 0;
  72. _fontSize = 13;
  73. _fontScale = 1;
  74. _singleW_Add = 20;
  75. _lineColor = _selectColor;
  76. _lineHeight = 2.5;
  77. _lineScale = 1;
  78. _arrowColor = _selectColor;
  79. _slideHeight = SCROLL_HEIGHT + 15;
  80. _slideColor = _deSelectColor;
  81. _slideCorner = _slideHeight/2;
  82. _slideScale = 1;
  83. _maxTitles = 5.0;
  84. _bottomLineColor = [UIColor grayColor];
  85. _bottomLineHeight = 1;
  86. }
  87. - (void)changeTitle:(NSArray *)titles {
  88. titlesArray = [titles mutableCopy];
  89. [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
  90. [self defaultAndCreateView];
  91. }
  92. #pragma mark - layout
  93. - (void)defaultAndCreateView {
  94. if (!titleWidthArray) {
  95. titleWidthArray = [NSMutableArray arrayWithCapacity:titlesArray.count];
  96. }
  97. [titleWidthArray removeAllObjects];
  98. _maxTitles = _maxTitles>titlesArray.count?titlesArray.count:_maxTitles;
  99. [self titlesWidth];
  100. if (_equalSize) {
  101. self.width = sum_width+_moreButton_width;
  102. if (titlesScroll) {
  103. titlesScroll.width = SCREEN_WIDTH;
  104. }
  105. if (slideScroll) {
  106. slideScroll.width = SCREEN_WIDTH;
  107. }
  108. }
  109. //判断总宽度
  110. if (sum_width > SCROLL_WIDTH && _layoutStyle== MLMSegmentLayoutCenter) {
  111. _layoutStyle = MLMSegmentLayoutLeft;
  112. }
  113. _showIndex = MIN(titlesArray.count-1, MAX(0, _showIndex));
  114. [self createView];
  115. if (_showIndex != 0) {
  116. currentIndex = _showIndex;
  117. [self changeContentOffset];
  118. [self changeBtnFrom:0 to:currentIndex];
  119. }
  120. }
  121. #pragma mark - 根据文字计算宽度
  122. - (void)titlesWidth {
  123. sum_width = 0;
  124. CGFloat width = SCROLL_WIDTH/_maxTitles;
  125. for (NSString *title in titlesArray) {
  126. if (_layoutStyle != MLMSegmentLayoutDefault) {
  127. width = [self titleWidth:title];
  128. }
  129. [titleWidthArray addObject:@(width)];
  130. sum_width += width;
  131. }
  132. if (self.btnBgImg.length) {
  133. sum_width += 24;
  134. }
  135. }
  136. - (CGFloat)titleWidth:(NSString *)title {
  137. if (!self.selectFont) {
  138. CGFloat sys_font = _fontScale>1?_fontSize*_fontScale:_fontSize;
  139. return [title boundingRectWithSize:CGSizeMake(MAXFLOAT, CGRectGetHeight(self.frame)) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:sys_font]} context:nil].size.width + _singleW_Add;
  140. }else{
  141. UIFont *sys_font = _fontScale==1?_selectFont:_deSelectFont;
  142. return [title boundingRectWithSize:CGSizeMake(MAXFLOAT, CGRectGetHeight(self.frame)) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName : sys_font} context:nil].size.width + _singleW_Add;
  143. }
  144. }
  145. //#pragma mark - 添加按钮
  146. //- (void)addMoreTitles:(NSArray *)moreTitles {
  147. // if (_layoutStyle == MLMSegmentLayoutCenter) {
  148. // return;
  149. // }
  150. //
  151. // CGFloat start_x = sum_width;
  152. // CGFloat start_index = titleWidthArray.count;
  153. //
  154. // //添加到数组,并计算宽度
  155. // for (NSInteger i = 0; i < moreTitles.count; i ++) {
  156. // NSString *title = moreTitles[i];
  157. // CGFloat width = [self titleWidth:title];
  158. // [titleWidthArray addObject:@(width)];
  159. // sum_width += width;
  160. //
  161. // [titlesArray addObject:title];
  162. // }
  163. //
  164. // [self createBtn:titlesArray addScroll:titlesScroll startX:start_x start_index:start_index];
  165. // if (_headStyle == SegmentHeadStyleSlide) {
  166. // [self createBtn:titlesArray addScroll:slideScroll startX:start_x start_index:start_index];
  167. // }
  168. //
  169. //
  170. // [self setSelectIndex:currentIndex];
  171. //}
  172. #pragma mark - create View
  173. - (void)createView {
  174. _fontScale = _headStyle==SegmentHeadStyleSlide?1:_fontScale;
  175. titlesScroll = [self customScroll];
  176. [self scrollViewSubviews:titlesScroll];
  177. [self addSubview:titlesScroll];
  178. if (_moreButton_width != 0) {
  179. _moreButton = [[UIView alloc] init];
  180. _moreButton.frame = CGRectMake(CGRectGetMaxX(titlesScroll.frame), 0, _moreButton_width, titlesScroll.height);
  181. [self addSubview:_moreButton];
  182. }
  183. if (_bottomLineHeight) {
  184. bottomLineView = [self bottomLineView];
  185. [self addSubview:bottomLineView];
  186. }
  187. switch (_headStyle) {
  188. case SegmentHeadStyleLine:
  189. {
  190. lineView = [self lineView];
  191. [titlesScroll addSubview:lineView];
  192. }
  193. break;
  194. case SegmentHeadStyleArrow:
  195. {
  196. _lineHeight = arrow_H;
  197. _lineScale = 1;
  198. lineView = [self lineView];
  199. lineView.backgroundColor = [UIColor clearColor];
  200. [titlesScroll addSubview:lineView];
  201. //arrow
  202. [self drawArrowLayer];
  203. arrow_layer.position = CGPointMake(lineView.width/2, lineView.height/2);
  204. [lineView.layer addSublayer:arrow_layer];
  205. }
  206. break;
  207. case SegmentHeadStyleSlide:
  208. {
  209. slideView = [self slideView];
  210. [titlesScroll addSubview:slideView];
  211. }
  212. break;
  213. default:
  214. break;
  215. }
  216. }
  217. #pragma mark - drow arrow
  218. - (void)drawArrowLayer {
  219. arrow_layer = [[CAShapeLayer alloc] init];
  220. arrow_layer.bounds = CGRectMake(0, 0, arrow_W, arrow_H);
  221. [arrow_layer setFillColor:_arrowColor.CGColor];
  222. UIBezierPath *arrowPath = [UIBezierPath bezierPath];
  223. [arrowPath moveToPoint:CGPointMake(arrow_W/2, 0)];
  224. [arrowPath addLineToPoint:CGPointMake(arrow_W, arrow_H)];
  225. [arrowPath addLineToPoint:CGPointMake(0, arrow_H)];
  226. [arrowPath closePath];
  227. arrow_layer.path = arrowPath.CGPath;
  228. }
  229. #pragma mark - create customScroll
  230. - (UIScrollView *)customScroll {
  231. if (!titlesArray) {
  232. return nil;
  233. }
  234. UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, SCROLL_WIDTH, SCROLL_HEIGHT)];
  235. scroll.contentSize = CGSizeMake(MAX(SCROLL_WIDTH, sum_width), SCROLL_HEIGHT);
  236. scroll.backgroundColor = _headColor;
  237. scroll.showsVerticalScrollIndicator = NO;
  238. scroll.showsHorizontalScrollIndicator = NO;
  239. scroll.bounces = NO;
  240. return scroll;
  241. }
  242. #pragma mark - titlesScroll subviews - yes or slideScroll subviews - no
  243. - (void)scrollViewSubviews:(UIScrollView*)scroll {
  244. BOOL titles = [scroll isEqual:titlesScroll];
  245. CGFloat start_x = 0;
  246. if (_layoutStyle == MLMSegmentLayoutCenter) {
  247. //计算布局的起点
  248. start_x = SCROLL_WIDTH/2;
  249. for (NSInteger i = 0; i < titleWidthArray.count/2; i ++) {
  250. start_x -= CURRENT_WIDTH(i);
  251. }
  252. if (titlesArray.count%2 != 0) {
  253. start_x -= CURRENT_WIDTH(titleWidthArray.count/2)/2;
  254. }
  255. }
  256. [self createBtn:titlesArray addScroll:scroll startX:start_x start_index:0];
  257. if (titles && _headStyle != SegmentHeadStyleSlide) {
  258. UIButton *curBtn = buttonArray[_showIndex];
  259. if (!_selectFont) {
  260. if (_fontScale != 1) {
  261. curBtn.titleLabel.font = [UIFont systemFontOfSize:_fontSize*_fontScale];
  262. }
  263. }else{
  264. curBtn.titleLabel.font = _selectFont;
  265. }
  266. [curBtn setTintColor:_selectColor];
  267. }
  268. }
  269. #pragma mark - createBtn
  270. - (void)createBtn:(NSArray *)titlesArr addScroll:(UIScrollView*)scroll startX:(CGFloat)start_x start_index:(NSInteger)start_index {
  271. BOOL titles = [scroll isEqual:titlesScroll];
  272. CGFloat width;
  273. for (NSInteger i = start_index; i < titlesArr.count; i ++) {
  274. if (self.tag == 1101) {
  275. width = CURRENT_WIDTH(i) + 10;
  276. }else{
  277. width = CURRENT_WIDTH(i);
  278. }
  279. UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
  280. [button setTitle:titlesArr[i] forState:UIControlStateNormal];
  281. if (!_selectFont) {
  282. button.titleLabel.font = [UIFont systemFontOfSize:_fontSize];
  283. }else{
  284. button.titleLabel.font = _deSelectFont;
  285. }
  286. if (self.tag == 1101) {
  287. button.frame = CGRectMake(start_x, 0, width, self.height);
  288. start_x += width;
  289. }else{
  290. button.frame = CGRectMake(start_x, 0, width, _slideHeight);
  291. start_x += (width + 15);
  292. }
  293. if (titles) {
  294. [button setTintColor:_deSelectColor];
  295. [button addTarget:self action:@selector(selectedHeadTitles:) forControlEvents:UIControlEventTouchUpInside];
  296. [buttonArray addObject:button];
  297. if (self.btnBgImg) {
  298. [button setBackgroundImage:[UIImage imageNamed:self.btnBeforeBgImg] forState:UIControlStateNormal];
  299. }
  300. //
  301. UIImageView *imgV = [[UIImageView alloc] initWithFrame:button.frame];
  302. [scroll addSubview:imgV];
  303. [backImgArray addObject:imgV];
  304. } else {
  305. [button setTintColor:_selectColor];
  306. }
  307. [scroll addSubview:button];
  308. }
  309. scroll.contentSize = CGSizeMake(MAX(SCROLL_WIDTH, sum_width), SCROLL_HEIGHT);
  310. }
  311. - (void)setBackImages:(NSArray *)backImages {
  312. _backImages = backImages;
  313. NSInteger count = MIN(backImages.count, backImgArray.count);
  314. for (NSInteger i = 0; i < count; i ++) {
  315. UIImageView *imageV = backImgArray[i];
  316. [imageV setImage:backImages[i]];
  317. if (i == currentIndex) {
  318. imageV.alpha = 1;
  319. } else {
  320. imageV.alpha = 0;
  321. }
  322. }
  323. }
  324. #pragma mark - create Line
  325. - (UIView *)lineView {
  326. _lineScale = fabs(_lineScale)>1?1:fabs(_lineScale);
  327. CGFloat line_w = CURRENT_WIDTH(currentIndex);
  328. UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, SCROLL_HEIGHT-_lineHeight, line_w*_lineScale, _lineHeight)];
  329. UIButton *current_btn = buttonArray[currentIndex];
  330. line.center = CGPointMake(current_btn.center.x, line.center.y);
  331. line.backgroundColor = _lineColor;
  332. return line;
  333. }
  334. #pragma mark - bottom Line
  335. - (UIView *)bottomLineView {
  336. UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, SCROLL_HEIGHT, self.width, _bottomLineHeight)];
  337. line.backgroundColor = _bottomLineColor;
  338. return line;
  339. }
  340. #pragma mark - create slide
  341. - (UIView *)slideView {
  342. CGFloat slide_w = CURRENT_WIDTH(currentIndex);
  343. UIView *slide = [[UIView alloc] initWithFrame:CGRectMake(0, (SCROLL_HEIGHT-_slideHeight)/2, slide_w*_slideScale, _slideHeight)];
  344. UIButton *current_btn = buttonArray[currentIndex];
  345. slide.center = CGPointMake(current_btn.center.x, slide.center.y);
  346. slide.clipsToBounds = YES;
  347. slide.layer.cornerRadius = MIN(_slideCorner, _slideHeight/2);
  348. slide.backgroundColor = _slideColor;
  349. slideScroll = [self customScroll];
  350. slideScroll.hidden = YES;//用不到这东西
  351. [self scrollViewSubviews:slideScroll];
  352. slideScroll.userInteractionEnabled = NO;
  353. slideScroll.backgroundColor = [UIColor clearColor];
  354. CGRect convertRect = [slide convertRect:titlesScroll.frame fromView:titlesScroll.superview];
  355. slideScroll.frame = CGRectMake(convertRect.origin.x, -(SCROLL_HEIGHT - _slideHeight)/2, SCROLL_WIDTH, SCROLL_HEIGHT);
  356. [slide addSubview:slideScroll];
  357. return slide;
  358. }
  359. #pragma mark - button Action
  360. - (void)selectedHeadTitles:(UIButton *)button {
  361. NSInteger selectIndex = [buttonArray indexOfObject:button];
  362. [self changeIndex:selectIndex completion:YES];
  363. }
  364. #pragma mark - 点击结束
  365. - (void)animationEnd {
  366. isSelected = NO;
  367. }
  368. #pragma mark - set index
  369. - (void)setSelectIndex:(NSInteger)index {
  370. // if (index == currentIndex) {
  371. // return;
  372. // }
  373. // //before
  374. // NSInteger before = currentIndex;
  375. // currentIndex = index;
  376. // [self changeContentOffset];
  377. // //select
  378. // [UIView animateWithDuration:animation_time animations:^{
  379. // [self changeBtnFrom:before to:currentIndex];
  380. // } completion:^(BOOL finished) {
  381. // }];
  382. // isSelected = YES;
  383. // if ([self.delegate respondsToSelector:@selector(didSelectedIndex:)]) {
  384. // [self.delegate didSelectedIndex:currentIndex];
  385. // } else if (self.selectedIndex) {
  386. // self.selectedIndex(currentIndex);
  387. // }
  388. [self changeIndex:index completion:NO];
  389. }
  390. - (void)changeIndex:(NSInteger)index completion:(BOOL)completion {
  391. if (index == currentIndex) {
  392. return;
  393. }
  394. //before
  395. NSInteger before = currentIndex;
  396. currentIndex = index;
  397. [self changeContentOffset];
  398. //select
  399. [UIView animateWithDuration:animation_time animations:^{
  400. } completion:^(BOOL finished) {
  401. [self changeBtnFrom:before to:currentIndex];
  402. }];
  403. isSelected = YES;
  404. if (completion) {
  405. if ([self.delegate respondsToSelector:@selector(didSelectedIndex:)]) {
  406. [self.delegate didSelectedIndex:currentIndex];
  407. } else if (self.selectedIndex) {
  408. self.selectedIndex(currentIndex);
  409. }
  410. }
  411. }
  412. - (void)changeContentOffset {
  413. if (sum_width > SCROLL_WIDTH) {
  414. UIButton *currentBtn = buttonArray[currentIndex];
  415. if (currentBtn.center.x<SCROLL_WIDTH/2) {
  416. [titlesScroll setContentOffset:CGPointMake(0, 0) animated:YES];
  417. } else if (currentBtn.center.x > (sum_width-SCROLL_WIDTH/2)) {
  418. [titlesScroll setContentOffset:CGPointMake(sum_width-SCROLL_WIDTH, 0) animated:YES];
  419. } else {
  420. [titlesScroll setContentOffset:CGPointMake(currentBtn.center.x - SCROLL_WIDTH/2, 0) animated:YES];
  421. }
  422. }
  423. }
  424. - (void)changeBtnFrom:(NSInteger)from to:(NSInteger)to {
  425. UIButton *before_btn = buttonArray[from];
  426. UIButton *select_btn = buttonArray[to];
  427. // if (_headStyle != SegmentHeadStyleSlide) {
  428. [before_btn setTintColor:_deSelectColor];
  429. [select_btn setTintColor:_selectColor];
  430. // }
  431. if (!_selectFont) {
  432. if (_fontScale) {
  433. before_btn.titleLabel.font = [UIFont systemFontOfSize:_fontSize];
  434. select_btn.titleLabel.font = [UIFont systemFontOfSize:_fontSize*_fontScale];
  435. }
  436. }else{
  437. before_btn.titleLabel.font = _deSelectFont;
  438. select_btn.titleLabel.font = _selectFont;
  439. }
  440. if (lineView) {
  441. lineView.width = select_btn.width*_lineScale;
  442. lineView.center = CGPointMake(select_btn.center.x, lineView.center.y);
  443. }
  444. if (arrow_layer) {
  445. arrow_layer.position = CGPointMake(lineView.width/2, lineView.height/2);
  446. }
  447. if (slideView) {
  448. //slide位置变化
  449. slideView.width = select_btn.width*_slideScale;
  450. slideView.center = CGPointMake(select_btn.center.x, slideView.center.y);
  451. //偏移
  452. CGRect convertRect = [slideView convertRect:titlesScroll.frame fromView:titlesScroll];
  453. slideScroll.frame = CGRectMake(convertRect.origin.x, convertRect.origin.y, slideScroll.contentSize.width, slideScroll.contentSize.height);
  454. }
  455. if (_hadBackImg) {
  456. UIImageView *before_img = backImgArray[from];
  457. UIImageView *select_img = backImgArray[to];
  458. before_img.alpha = 0;
  459. select_img.alpha = 1;
  460. }
  461. if (self.btnBgImg) {
  462. [select_btn setBackgroundImage:[UIImage imageNamed:self.btnBgImg] forState:UIControlStateNormal];
  463. [before_btn setBackgroundImage:[UIImage imageNamed:self.btnBeforeBgImg] forState:UIControlStateNormal];
  464. }else{
  465. [before_btn setBackgroundImage:nil forState:UIControlStateNormal];
  466. }
  467. }
  468. #pragma mark - animation
  469. //外部关联的scrollView变化
  470. - (void)changePointScale:(CGFloat)scale {
  471. if (isSelected) {
  472. return;
  473. }
  474. if (scale<0) {
  475. return;
  476. }
  477. //区分向左 还是向右
  478. BOOL left = endScale > scale;
  479. endScale = scale;
  480. //1.将scale变为对应titleScroll的titleScale
  481. //每个view所占的百分比
  482. CGFloat per_view = 1.0/(CGFloat)titlesArray.count;
  483. //下标
  484. NSInteger changeIndex = scale/per_view + (left?1:0);
  485. NSInteger nextIndex = changeIndex + (left?-1:1);
  486. //超出范围
  487. if (nextIndex >= titlesArray.count || changeIndex >= titlesArray.count) {
  488. return;
  489. }
  490. //currentbtn
  491. UIButton *currentBtn = buttonArray[changeIndex];
  492. UIButton *nextBtn = buttonArray[nextIndex];
  493. //startscla
  494. CGFloat start_scale = 0;
  495. for (NSInteger i = 0; i < nextIndex; i++) {
  496. start_scale += CURRENT_WIDTH(i)/sum_width;
  497. }
  498. //滑动选中位置所占的相对百分比
  499. CGFloat current_title_Scale = CURRENT_WIDTH(changeIndex)/sum_width;
  500. //单个view偏移的百分比
  501. CGFloat single_offset_scale = (scale - per_view*changeIndex)/per_view;
  502. //转换成对应title的百分比
  503. CGFloat titleScale = single_offset_scale * current_title_Scale + start_scale;
  504. //变化的百分比
  505. CGFloat change_scale = (left?-1:1)*(titleScale - start_scale)/current_title_Scale;
  506. switch (_headStyle) {
  507. case SegmentHeadStyleDefault:
  508. case SegmentHeadStyleLine:
  509. case SegmentHeadStyleArrow:
  510. {
  511. if (lineView) {
  512. //lineView位置变化
  513. lineView.width = [self widthChangeCurWidth:CURRENT_WIDTH(changeIndex) nextWidth:CURRENT_WIDTH(nextIndex) changeScale:change_scale endScale:_lineScale];
  514. CGFloat center_x = [self centerChanegCurBtn:currentBtn nextBtn:nextBtn changeScale:change_scale];
  515. lineView.center = CGPointMake(center_x, lineView.center.y);
  516. }
  517. if (arrow_layer) {
  518. arrow_layer.position = CGPointMake(lineView.width/2, lineView.height/2);
  519. }
  520. //颜色变化
  521. [self colorChangeCurBtn:currentBtn nextBtn:nextBtn changeScale:change_scale];
  522. //字体大小变化
  523. [self fontChangeCurBtn:currentBtn nextBtn:nextBtn changeScale:change_scale];
  524. //背景图片
  525. if (_hadBackImg) {
  526. UIImageView *current_img = backImgArray[changeIndex];
  527. UIImageView *next_img = backImgArray[nextIndex];
  528. [self backImgCurImg:current_img nextImg:next_img changeScale:change_scale];
  529. }
  530. }
  531. break;
  532. case SegmentHeadStyleSlide:
  533. {
  534. //slide位置变化
  535. slideView.width = [self widthChangeCurWidth:CURRENT_WIDTH(changeIndex) nextWidth:CURRENT_WIDTH(nextIndex) changeScale:change_scale endScale:_slideScale];
  536. CGFloat center_x = [self centerChanegCurBtn:currentBtn nextBtn:nextBtn changeScale:change_scale];
  537. slideView.center = CGPointMake(center_x, slideView.center.y);
  538. //偏移
  539. CGRect convertRect = [slideView convertRect:titlesScroll.frame fromView:titlesScroll];
  540. slideScroll.frame = CGRectMake(convertRect.origin.x, convertRect.origin.y, slideScroll.contentSize.width, slideScroll.contentSize.height);
  541. }
  542. break;
  543. default:
  544. break;
  545. }
  546. }
  547. #pragma mark - 长度变化
  548. - (CGFloat)widthChangeCurWidth:(CGFloat)curWidth nextWidth:(CGFloat)nextWidth changeScale:(CGFloat)changeScale endScale:(CGFloat)endscale{
  549. //改变的宽度
  550. CGFloat change_width = curWidth - nextWidth;
  551. //宽度变化
  552. CGFloat width = curWidth*endscale - changeScale * change_width;
  553. return width;
  554. }
  555. #pragma mark - 中心位置的变化
  556. - (CGFloat)centerChanegCurBtn:(UIButton *)curBtn nextBtn:(UIButton *)nextBtn changeScale:(CGFloat)changeScale {
  557. //lineView改变的中心
  558. CGFloat change_center = nextBtn.center.x - curBtn.center.x;
  559. //lineView位置变化
  560. CGFloat center_x = curBtn.center.x + changeScale * change_center;
  561. return center_x;
  562. }
  563. #pragma mark - 字体大小变化
  564. - (void)fontChangeCurBtn:(UIButton *)curBtn nextBtn:(UIButton *)nextBtn changeScale:(CGFloat)changeScale{
  565. if (!_selectFont) {
  566. //button字体改变的大小
  567. CGFloat btn_font_change = _fontSize*(_fontScale - 1);
  568. //大小变化
  569. CGFloat next_font = _fontSize + changeScale*btn_font_change;
  570. CGFloat cur_font = _fontSize*_fontScale - changeScale*btn_font_change;
  571. nextBtn.titleLabel.font = [UIFont systemFontOfSize:next_font];
  572. curBtn.titleLabel.font = [UIFont systemFontOfSize:cur_font];
  573. }else{
  574. nextBtn.titleLabel.font = _deSelectFont;
  575. curBtn.titleLabel.font = _selectFont;
  576. }
  577. }
  578. #pragma mark - 颜色变化
  579. - (void)colorChangeCurBtn:(UIButton *)curBtn nextBtn:(UIButton *)nextBtn changeScale:(CGFloat)changeScale {
  580. //button选中颜色
  581. CGFloat sel_red;
  582. CGFloat sel_green;
  583. CGFloat sel_blue;
  584. CGFloat sel_alpha;
  585. //button未选中的颜色
  586. CGFloat de_sel_red;
  587. CGFloat de_sel_green;
  588. CGFloat de_sel_blue;
  589. CGFloat de_sel_alpha;
  590. if ([_selectColor getRed:&sel_red green:&sel_green blue:&sel_blue alpha:&sel_alpha] && [_deSelectColor getRed:&de_sel_red green:&de_sel_green blue:&de_sel_blue alpha:&de_sel_alpha]) {
  591. //颜色的变化的大小
  592. CGFloat red_changge = sel_red - de_sel_red;
  593. CGFloat green_changge = sel_green - de_sel_green;
  594. CGFloat blue_changge = sel_blue - de_sel_blue;
  595. CGFloat alpha_changge = sel_alpha - de_sel_alpha;
  596. //颜色变化
  597. [nextBtn setTintColor:[UIColor colorWithRed:de_sel_red + red_changge*changeScale
  598. green:de_sel_green + green_changge*changeScale
  599. blue:de_sel_blue + blue_changge*changeScale
  600. alpha:de_sel_alpha + alpha_changge*changeScale]];
  601. [curBtn setTintColor:[UIColor colorWithRed:sel_red - red_changge*changeScale
  602. green:sel_green - green_changge*changeScale
  603. blue:sel_blue - blue_changge*changeScale
  604. alpha:sel_alpha - alpha_changge*changeScale]];
  605. }
  606. }
  607. #pragma mark - 背景图渐变
  608. - (void)backImgCurImg:(UIImageView *)curback nextImg:(UIImageView *)nextback changeScale:(CGFloat)changeScale {
  609. //alpha变化
  610. CGFloat next_alpha = changeScale;
  611. CGFloat cur_alpha = 1 - changeScale;
  612. nextback.alpha = next_alpha>.8?1.:next_alpha;
  613. curback.alpha = cur_alpha<.2?0:cur_alpha;
  614. }
  615. #pragma mark - get sumWidth
  616. - (CGFloat)getSumWidth {
  617. return sum_width;
  618. }
  619. #pragma mark - lineView
  620. - (UIView *)getLineView {
  621. return lineView;
  622. }
  623. - (UIView *)getBottomLineView {
  624. return bottomLineView;
  625. }
  626. - (UIView *)getScrollLineView {
  627. if (_headStyle == SegmentHeadStyleLine) {
  628. return lineView;
  629. } else {
  630. return nil;
  631. }
  632. }
  633. #pragma mark - dealloc
  634. - (void)dealloc {
  635. arrow_layer.delegate = nil;
  636. [arrow_layer removeFromSuperlayer];
  637. arrow_layer = nil;
  638. }
  639. - (UIScrollView *)titlesScroll {
  640. return titlesScroll;
  641. }
  642. - (NSArray *)buttons {
  643. return buttonArray;
  644. }
  645. @end