MenuSegmentView.m 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. //
  2. // MenuSegmentView.m
  3. // DDTG
  4. //
  5. // Created by 翟玉磊 on 16/5/11.
  6. // Copyright © 2016年 翟玉磊. All rights reserved.
  7. //
  8. #define DEFAULT_DURATION 0.3f //动画时间
  9. #import "MenuSegmentView.h"
  10. @interface MenuSegmentView () {
  11. NSMutableArray *buttonArray;
  12. NSMutableArray *badegArray;
  13. }
  14. @property (nonatomic, assign) CGFloat viewWidth;
  15. @property (nonatomic, assign) CGFloat viewHeight;
  16. @property (nonatomic, assign) CGFloat labelWidth;
  17. @property (nonatomic, assign) NSInteger selectIndex;
  18. @property (nonatomic, strong) UIView *heightLightView;
  19. @property (nonatomic, strong) UIView *heightTopView;
  20. @property (nonatomic, strong) UIView *heightColorView;
  21. @property (nonatomic, readwrite, strong) UIView *bottomLine;
  22. @property (nonatomic, strong) ButtonOnClickBlock buttonBlock;
  23. @property (nonatomic, strong) SelectIndexBlock selectIndexBlock;
  24. @end
  25. @implementation MenuSegmentView
  26. - (instancetype)initWithFrame:(CGRect)frame titles:(NSArray *)array {
  27. if (self = [super initWithFrame:frame]) {
  28. _titles = array;
  29. _viewHeight = self.f_heigh;
  30. _viewWidth = self.f_width;
  31. _duration = DEFAULT_DURATION;
  32. [self initValue];
  33. }
  34. return self;
  35. }
  36. - (void)initValue {
  37. // 初始化数据
  38. self.selectIndex = 0;
  39. _isShowBottomLine = YES;
  40. _selectedLineHeight = 2;
  41. buttonArray = [NSMutableArray array];
  42. [self customeData];
  43. [self createBottomLabels];
  44. [self createTopLabels];
  45. [self createTopButtons];
  46. [self createBadgeViews];
  47. }
  48. - (void)setSelectedItemIndex:(int)page {
  49. [self selectedAnimation:page];
  50. }
  51. //更新titles
  52. - (void)updateTitlesWithData:(NSArray *)array {
  53. _titles = [NSArray arrayWithArray:[array copy]];
  54. // 删除子视图
  55. for (UIView *view in self.subviews) {
  56. [view removeFromSuperview];
  57. }
  58. // 创建
  59. [self initValue];
  60. }
  61. - (void)setIsShowBottomLine:(BOOL)isShowBottomLine {
  62. _isShowBottomLine = isShowBottomLine;
  63. if (_isShowBottomLine) {
  64. _bottomLine.hidden = NO;
  65. }else {
  66. _bottomLine.hidden = YES;
  67. }
  68. }
  69. - (void)setSelectedLineHeight:(CGFloat)selectedLineHeight {
  70. _selectedLineHeight = selectedLineHeight;
  71. if (_heightTopView) {
  72. _heightColorView.frame = CGRectMake(_heightColorView.f_x, self.f_heigh - selectedLineHeight, _heightColorView.f_width, selectedLineHeight);
  73. [_heightColorView addViewBorder:Color_Clear redian:_selectedLineHeight/2];
  74. }
  75. }
  76. /**
  77. 显示或者隐藏指定索引的红点
  78. @param index 索引
  79. @param status YES显示 NO隐藏
  80. */
  81. - (void)updateBadgeWithIndex:(NSInteger)index status:(BOOL)status {
  82. for (NSInteger i = 0; i < badegArray.count; i++) {
  83. if (i == index) {
  84. UIView *badge = [badegArray objectAtIndex:i];
  85. badge.hidden = !status;
  86. break;
  87. }
  88. }
  89. }
  90. - (void)setTitleFont:(UIFont *)titleFont {
  91. }
  92. //回调
  93. - (void)setButtonOnClickBlock:(ButtonOnClickBlock) block {
  94. if (block) {
  95. _buttonBlock = block;
  96. }
  97. }
  98. /**
  99. * 提供默认信息
  100. */
  101. - (void)customeData {
  102. _titleDefaultColor = Color_TextFont;
  103. _titleSelectColor = Color_Button_Select;
  104. _titleFont = Font_B(18);
  105. _labelWidth = _viewWidth / _titles.count;
  106. }
  107. /**
  108. * 创建底部层的label
  109. */
  110. - (void)createBottomLabels {
  111. for (int i = 0; i < _titles.count; i ++) {
  112. UILabel *tempLabel = [self createLabelWithTitlesIndex:i textColor:_titleDefaultColor];
  113. tempLabel.font = _titleFont;
  114. [self addSubview:tempLabel];
  115. }
  116. if (_bottomLine == nil) {
  117. _bottomLine = [UIView createLineRect:CGRectMake(0, _viewHeight - 0.5, _viewWidth, 0.5)];
  118. [self addSubview:_bottomLine];
  119. }
  120. }
  121. /**
  122. * 创建上层高亮使用的label
  123. */
  124. - (void)createTopLabels {
  125. CGRect heightLabelFrame = CGRectMake(0, 0, _labelWidth, _viewHeight);
  126. _heightLightView = [[UIView alloc] initWithFrame:heightLabelFrame];
  127. _heightLightView.clipsToBounds = YES;
  128. _heightColorView = [[UIView alloc] initWithFrame:CGRectMake(0, _viewHeight - 2, _labelWidth, _selectedLineHeight)];
  129. [_heightColorView addViewBorder:Color_Clear redian:_selectedLineHeight/2];
  130. _heightColorView.backgroundColor = _titleSelectColor;
  131. [_heightLightView addSubview:_heightColorView];
  132. _heightTopView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _viewWidth, _viewHeight)];
  133. for (int i = 0; i < _titles.count; i ++) {
  134. UILabel *label = [self createLabelWithTitlesIndex:i textColor:_titleSelectColor];
  135. [_heightTopView addSubview:label];
  136. }
  137. [_heightLightView addSubview:_heightTopView];
  138. [self addSubview:_heightLightView];
  139. }
  140. - (void)createBadgeViews {
  141. badegArray = [NSMutableArray array];
  142. for (int i = 0; i < _titles.count; i ++) {
  143. CGFloat titleWidth = [HandleString lableWidth:_titles[i] withSize:CGSizeMake(MAXFLOAT, _viewHeight) withFont:_titleFont];
  144. CGFloat x = (_labelWidth - titleWidth) / 2 + titleWidth + 5.0f;
  145. UIView *badgeView = [[UIView alloc] initWithFrame:CGRectMake(x + _labelWidth * i, 10.0f, 5, 5)];
  146. badgeView.tag = i;
  147. [badgeView setBackgroundColor:[UIColor redColor]];
  148. badgeView.hidden = YES;
  149. [badgeView addViewBorder:Color_Clear redian:2.5];
  150. [self addSubview:badgeView];
  151. [badegArray addObject:badgeView];
  152. }
  153. }
  154. /**
  155. * 创建按钮
  156. */
  157. - (void)createTopButtons {
  158. buttonArray = [NSMutableArray new];
  159. for (int i = 0; i < _titles.count; i ++) {
  160. CGRect tempFrame = [self countCurrentRectWithIndex:i];
  161. UIButton *tempButton = [[UIButton alloc] initWithFrame:tempFrame];
  162. tempButton.tag = i;
  163. [tempButton setBackgroundColor:[UIColor clearColor]];
  164. [tempButton addTarget:self action:@selector(tapButton:) forControlEvents:UIControlEventTouchUpInside];
  165. [self addSubview:tempButton];
  166. [buttonArray addObject:tempButton];
  167. }
  168. }
  169. //点击事件
  170. - (void)tapButton:(UIButton *)sender {
  171. if (_buttonBlock && sender.tag < _titles.count) {
  172. _buttonBlock(sender.tag, _titles[sender.tag]);
  173. }
  174. // [self selectedAnimation:sender.tag];
  175. }
  176. - (void)selectedAnimation:(NSInteger)page {
  177. if (_selectIndex == page) {
  178. return;
  179. }
  180. _selectIndex = page;
  181. if (_selectIndexBlock) {
  182. _selectIndexBlock(_selectIndex);
  183. }
  184. CGRect frame = [self countCurrentRectWithIndex:page];
  185. CGRect changeFrame = [self countCurrentRectWithIndex:-page];
  186. __weak typeof(self) weak_self = self;
  187. [UIView animateWithDuration:_duration animations:^{
  188. self->_heightLightView.frame = frame;
  189. self->_heightTopView.frame = changeFrame;
  190. } completion:^(BOOL finished) {
  191. [weak_self shakeAnimationForView:self->_heightColorView];
  192. }];
  193. }
  194. - (CGRect)countCurrentRectWithIndex:(NSInteger)index {
  195. return CGRectMake(_labelWidth * index, 0, _labelWidth, _viewHeight);
  196. }
  197. /**
  198. * 感觉索引创建label
  199. *
  200. * @param index 创建的第几个index
  201. * @param textColor label字体颜色
  202. *
  203. * @return 返回创建好的label
  204. */
  205. - (UILabel *)createLabelWithTitlesIndex:(NSInteger)index textColor:(UIColor *)textColor {
  206. CGRect currentLabelFrame = [self countCurrentRectWithIndex:index];
  207. UILabel *label = [[UILabel alloc] initWithFrame:currentLabelFrame];
  208. label.text = _titles[index];
  209. label.textColor = textColor;
  210. label.font = _titleFont;
  211. label.tag = index + 10;
  212. label.minimumScaleFactor = 0.1f;
  213. label.textAlignment = NSTextAlignmentCenter;
  214. return label;
  215. }
  216. /**
  217. * 抖动效果
  218. *
  219. * @param view 要抖动的view
  220. */
  221. - (void)shakeAnimationForView:(UIView *) view {
  222. CALayer *viewLayer = view.layer;
  223. CGPoint position = viewLayer.position;
  224. CGPoint x = CGPointMake(position.x + 1, position.y);
  225. CGPoint y = CGPointMake(position.x - 1, position.y);
  226. CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
  227. [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
  228. [animation setFromValue:[NSValue valueWithCGPoint:x]];
  229. [animation setToValue:[NSValue valueWithCGPoint:y]];
  230. [animation setAutoreverses:YES];
  231. [animation setDuration:.06];
  232. [animation setRepeatCount:3];
  233. [viewLayer addAnimation:animation forKey:nil];
  234. }
  235. @end