MOScrollMenuView.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. //
  2. // MOScrollMenuView.m
  3. // powerone
  4. //
  5. // Created by SuperC on 2019/8/8.
  6. // Copyright © 2019 onecloud.ltd. All rights reserved.
  7. //
  8. #define TitleFont 12.0
  9. #define ImageViewWidthAndHeight 18.0
  10. #define ImageViewX 10.0
  11. #import "MOScrollMenuView.h"
  12. #import "UIView+Extension.h"
  13. #import "MOCountryList.h"
  14. #import "MOThemeManager.h"
  15. @implementation MOCountryBtn
  16. - (void)layoutSubviews{
  17. [super layoutSubviews];
  18. if(self.imageView.image != nil)
  19. {
  20. self.imageView.width = ImageViewWidthAndHeight;
  21. self.imageView.height = ImageViewWidthAndHeight;
  22. self.imageView.x = ImageViewX;
  23. self.imageView.centerY = self.centerY;
  24. UIFont *customFont = [UIFont fontWithName:kNormalContentFontStr size:12.0];
  25. if(!customFont){
  26. customFont = [MOTextTools MODisplayFontWithSize:12.0 bold:YES itatic:YES weight:UIFontWeightMedium];
  27. }
  28. CGFloat width = [MOTools getWidthWithString:self.titleLabel.text font:customFont] + 2.0;
  29. self.titleLabel.frame = CGRectMake(CGRectGetMaxX(self.imageView.frame) + 2, 0, width, (TitleFont + 2.0));
  30. self.titleLabel.centerY = self.imageView.centerY;
  31. self.titleLabel.textAlignment = NSTextAlignmentCenter;
  32. }
  33. }
  34. @end
  35. @implementation MOScrollMenuView
  36. {
  37. /** 用于记录最后创建的控件 */
  38. UIView *_lastView;
  39. /** 按钮下面的横线 */
  40. UIView *_lineView;
  41. }
  42. #pragma mark - 重写构造方法
  43. /** 重写构造方法 */
  44. - (instancetype)initWithFrame:(CGRect)frame
  45. {
  46. if (self = [super initWithFrame:frame])
  47. {
  48. self.showsHorizontalScrollIndicator = NO;
  49. self.contentInset = UIEdgeInsetsMake(0, 0, 0, 10);
  50. _currentButtonIndex = 0; // 默认当前选择的按钮是第一个
  51. }
  52. return self;
  53. }
  54. - (void)layoutSubviews {
  55. [super layoutSubviews];
  56. if (!self.layer.mask) {
  57. CAGradientLayer *maskLayer = [CAGradientLayer layer];
  58. // 设置水平渐变
  59. maskLayer.startPoint = CGPointMake(0.0, 0.5);
  60. maskLayer.endPoint = CGPointMake(1.0, 0.5);
  61. maskLayer.locations = @[@0.0, @0.1, @0.9, @1.0];
  62. maskLayer.bounds = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
  63. maskLayer.anchorPoint = CGPointZero;
  64. self.layer.mask = maskLayer;
  65. }
  66. [self updateGradientMask];
  67. }
  68. - (void)updateGradientMask {
  69. CGColorRef outerColor = [UIColor colorWithWhite:1.0 alpha:0.0].CGColor;
  70. CGColorRef innerColor = [UIColor colorWithWhite:1.0 alpha:1.0].CGColor;
  71. if (self.contentOffset.x <= 0) {
  72. // 最左边
  73. ((CAGradientLayer *)self.layer.mask).colors = @[
  74. (__bridge id)innerColor,
  75. (__bridge id)innerColor,
  76. (__bridge id)innerColor,
  77. (__bridge id)outerColor
  78. ];
  79. } else if (self.contentOffset.x + self.frame.size.width >= self.contentSize.width) {
  80. // 最右边
  81. ((CAGradientLayer *)self.layer.mask).colors = @[
  82. (__bridge id)outerColor,
  83. (__bridge id)innerColor,
  84. (__bridge id)innerColor,
  85. (__bridge id)innerColor
  86. ];
  87. } else {
  88. // 中间
  89. ((CAGradientLayer *)self.layer.mask).colors = @[
  90. (__bridge id)outerColor,
  91. (__bridge id)innerColor,
  92. (__bridge id)innerColor,
  93. (__bridge id)outerColor
  94. ];
  95. }
  96. [CATransaction begin];
  97. [CATransaction setDisableActions:YES];
  98. self.layer.mask.position = CGPointMake(self.contentOffset.x, 0); // 水平方向偏移
  99. [CATransaction commit];
  100. }
  101. - (void)setContentOffset:(CGPoint)contentOffset {
  102. [super setContentOffset:contentOffset];
  103. [self updateGradientMask];
  104. }
  105. - (void)reloadData {
  106. [self setTitleArray:_titleArray];
  107. WEAKSELF
  108. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  109. [weakSelf setCurrentButtonIndex:weakSelf.currentButtonIndex];
  110. });
  111. }
  112. #pragma mark - 赋值标题数组
  113. /** 赋值标题数组 */
  114. - (void)setTitleArray:(NSArray *)titleArray
  115. {
  116. _titleArray = titleArray;
  117. // 先将所有子控件移除
  118. for (UIView *subView in self.subviews)
  119. {
  120. [subView removeFromSuperview];
  121. }
  122. // 将lastView置空
  123. _lastView = nil;
  124. // 遍历标题数组
  125. [_titleArray enumerateObjectsUsingBlock:^(MOCountryList * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop)
  126. {
  127. __block MOCountryBtn *menuButton = [MOCountryBtn buttonWithType:UIButtonTypeCustom];
  128. [self addSubview:menuButton];
  129. if (_lastView)
  130. {
  131. menuButton.frame = CGRectMake(_lastView.maxX + 10, 0, 100, self.height);
  132. }
  133. else
  134. {
  135. menuButton.frame = CGRectMake(0, 0, 100, self.height);
  136. }
  137. menuButton.layer.masksToBounds = YES;
  138. menuButton.layer.cornerRadius = self.height / 2.0;
  139. menuButton.tag = 100 + idx;
  140. if(obj.icon.length > 0){
  141. [menuButton sd_setImageWithURL:[NSURL URLWithString:obj.icon] forState:UIControlStateNormal];
  142. [menuButton sd_setImageWithURL:[NSURL URLWithString:obj.icon] forState:UIControlStateSelected];
  143. }
  144. else{
  145. [menuButton sd_setImageWithURL:[NSURL URLWithString:@""] forState:UIControlStateNormal];
  146. [menuButton sd_setImageWithURL:[NSURL URLWithString:@""] forState:UIControlStateSelected];
  147. }
  148. menuButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
  149. UIFont *customFont = [UIFont fontWithName:kNormalContentFontStr size:12.0];
  150. if(!customFont){
  151. customFont = [MOTextTools MODisplayFontWithSize:12.0 bold:YES itatic:YES weight:UIFontWeightMedium];
  152. }
  153. [menuButton.titleLabel setFont:customFont];
  154. [menuButton setTitleColor:[MOTools colorWithHexString:@"#26252A" alpha:1.0] forState:UIControlStateNormal];
  155. if ([MOThemeManager shareManager].canUseTheme && [MOThemeManager shareManager].themeModel.countryColor.length > 0) {
  156. [menuButton setTitleColor:[MOTools colorWithHexString:[MOThemeManager shareManager].themeModel.countryColor] forState:UIControlStateNormal];
  157. }
  158. [menuButton setTitleColor:[MOTools colorWithHexString:@"#26252A" alpha:1.0] forState:UIControlStateSelected];
  159. if ([MOThemeManager shareManager].canUseTheme && [MOThemeManager shareManager].themeModel.countryColorOn.length > 0) {
  160. [menuButton setTitleColor:[MOTools colorWithHexString:[MOThemeManager shareManager].themeModel.countryColorOn] forState:UIControlStateSelected];
  161. }
  162. [menuButton setTitle:obj.name forState:UIControlStateNormal];
  163. [menuButton setTitle:obj.name forState:UIControlStateSelected];
  164. menuButton.backgroundColor = [MOTools colorWithHexString:@"#FFFFFF" alpha:1.0];
  165. if ([MOThemeManager shareManager].canUseTheme && [MOThemeManager shareManager].themeModel.countryBgColor.length > 0) {
  166. menuButton.backgroundColor = [MOTools colorWithHexString:[MOThemeManager shareManager].themeModel.countryBgColor];
  167. }
  168. [menuButton addTarget:self action:@selector(menuButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
  169. // 宽度自适应
  170. [menuButton sizeToFit];
  171. if(obj.icon.length > 0){
  172. CGFloat labebTextWidth = [MOTools getWidthWithString:obj.name font:customFont] + 2.0;
  173. CGFloat labelWidth = ImageViewX * 2.0 + ImageViewWidthAndHeight + labebTextWidth;
  174. menuButton.width = labelWidth;
  175. }
  176. else{
  177. menuButton.width = menuButton.width + 20.0;
  178. }
  179. menuButton.height = self.height;
  180. // 这句不能少,不然初始化时button的label的宽度为0
  181. [menuButton layoutIfNeeded];
  182. // 默认第一个按钮时选中状态
  183. if (idx == 0)
  184. {
  185. menuButton.selected = YES;
  186. menuButton.backgroundColor = [MOTools colorWithHexString:@"#16E0FE" alpha:1.0];
  187. if ([MOThemeManager shareManager].canUseTheme && [MOThemeManager shareManager].themeModel.countryBgColorOn.length > 0) {
  188. menuButton.backgroundColor = [MOTools colorWithHexString:[MOThemeManager shareManager].themeModel.countryBgColorOn];
  189. }
  190. }
  191. _lastView = menuButton;
  192. }];
  193. self.contentSize = CGSizeMake(CGRectGetMaxX(_lastView.frame), CGRectGetHeight(self.frame));
  194. }
  195. #pragma mark - 菜单按钮点击
  196. /** 菜单按钮点击 */
  197. - (void)menuButtonClicked:(MOCountryBtn *)sender
  198. {
  199. // 改变按钮的选中状态
  200. // for (MOCountryBtn *button in self.subviews)
  201. // {
  202. // if ([button isKindOfClass:[MOCountryBtn class]])
  203. // {
  204. // button.selected = NO;
  205. // button.backgroundColor = [MOTools colorWithHexString:@"#F5F1F6" alpha:1.0];
  206. // button.layer.borderColor = [MOTools colorWithHexString:@"#F5F1F6" alpha:1.0].CGColor;
  207. // }
  208. // }
  209. // sender.selected = YES;
  210. // sender.backgroundColor = [MOTools colorWithHexString:@"#F0DAFD" alpha:1.0];
  211. // sender.layer.borderColor = [MOTools colorWithHexString:@"#E72DD3" alpha:1.0].CGColor;
  212. //
  213. // // 将所点击的button移到中间
  214. // if (_lastView.maxX > self.width)
  215. // {
  216. // if (sender.x >= self.width / 2 && sender.centerX <= self.contentSize.width - self.width/2)
  217. // {
  218. // [UIView animateWithDuration:0.3 animations:^
  219. // {
  220. // self.contentOffset = CGPointMake(sender.centerX - self.width / 2, 0);
  221. // }];
  222. // }
  223. // else if (sender.frame.origin.x < self.width / 2)
  224. // {
  225. // [UIView animateWithDuration:0.3 animations:^
  226. // {
  227. // self.contentOffset = CGPointMake(0, 0);
  228. // }];
  229. // }
  230. // else
  231. // {
  232. // [UIView animateWithDuration:0.3 animations:^
  233. // {
  234. // self.contentOffset = CGPointMake(self.contentSize.width - self.width, 0);
  235. // }];
  236. // }
  237. // }
  238. self.currentButtonIndex = sender.tag - 100;
  239. if (self.clickBtnBlock)
  240. {
  241. self.clickBtnBlock(sender.tag - 100);
  242. }
  243. }
  244. #pragma mark - 赋值当前选择的按钮
  245. /** 赋值当前选择的按钮 */
  246. - (void)setCurrentButtonIndex:(NSInteger)currentButtonIndex
  247. {
  248. _currentButtonIndex = currentButtonIndex;
  249. // 改变按钮的选中状态
  250. MOCountryBtn *currentButton = [self viewWithTag:(100 + currentButtonIndex)];
  251. for (MOCountryBtn *button in self.subviews)
  252. {
  253. if ([button isKindOfClass:[MOCountryBtn class]])
  254. {
  255. button.selected = NO;
  256. button.backgroundColor = [MOTools colorWithHexString:@"#FFFFFF" alpha:1.0];
  257. if ([MOThemeManager shareManager].canUseTheme && [MOThemeManager shareManager].themeModel.countryBgColor.length > 0) {
  258. button.backgroundColor = [MOTools colorWithHexString:[MOThemeManager shareManager].themeModel.countryBgColor];
  259. }
  260. }
  261. }
  262. currentButton.selected = YES;
  263. currentButton.backgroundColor = [MOTools colorWithHexString:@"#16E0FE" alpha:1.0];
  264. if ([MOThemeManager shareManager].canUseTheme && [MOThemeManager shareManager].themeModel.countryBgColorOn.length > 0) {
  265. currentButton.backgroundColor = [MOTools colorWithHexString:[MOThemeManager shareManager].themeModel.countryBgColorOn];
  266. }
  267. // 将所点击的button移到中间
  268. if (_lastView.maxX > self.width)
  269. {
  270. if (currentButton.x >= self.width / 2 && currentButton.centerX <= self.contentSize.width - self.width/2)
  271. {
  272. [UIView animateWithDuration:0.3 animations:^
  273. {
  274. self.contentOffset = CGPointMake(currentButton.centerX - self.width / 2, 0);
  275. }];
  276. }
  277. else if (currentButton.x < self.width / 2)
  278. {
  279. [UIView animateWithDuration:0.3 animations:^
  280. {
  281. self.contentOffset = CGPointMake(0, 0);
  282. }];
  283. }
  284. else
  285. {
  286. [UIView animateWithDuration:0.3 animations:^
  287. {
  288. self.contentOffset = CGPointMake(self.contentSize.width - self.width + self.contentInset.right, 0);
  289. }];
  290. }
  291. }
  292. }
  293. @end