JXCategoryTitleView.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. //
  2. // JXCategoryView.m
  3. // UI系列测试
  4. //
  5. // Created by jiaxin on 2018/3/15.
  6. // Copyright © 2018年 jiaxin. All rights reserved.
  7. //
  8. #import "JXCategoryTitleView.h"
  9. #import "JXCategoryFactory.h"
  10. @implementation JXCategoryTitleView
  11. - (void)initializeData {
  12. [super initializeData];
  13. _titleNumberOfLines = 1;
  14. _titleLabelZoomEnabled = NO;
  15. _titleLabelZoomScale = 1.2;
  16. _titleColor = [UIColor blackColor];
  17. _titleSelectedColor = [UIColor redColor];
  18. _titleFont = [UIFont systemFontOfSize:15];
  19. _titleColorGradientEnabled = NO;
  20. _titleLabelMaskEnabled = NO;
  21. _titleLabelZoomScrollGradientEnabled = YES;
  22. _titleLabelStrokeWidthEnabled = NO;
  23. _titleLabelSelectedStrokeWidth = -3;
  24. _titleLabelVerticalOffset = 0;
  25. _titleLabelAnchorPointStyle = JXCategoryTitleLabelAnchorPointStyleCenter;
  26. }
  27. - (UIFont *)titleSelectedFont {
  28. if (_titleSelectedFont) {
  29. return _titleSelectedFont;
  30. }
  31. return self.titleFont;
  32. }
  33. - (void)gk_refreshCellState {
  34. // 刷新cell颜色
  35. [self.dataSource enumerateObjectsUsingBlock:^(JXCategoryBaseCellModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  36. [self reloadCellAtIndex:idx];
  37. }];
  38. }
  39. - (void)gk_refreshIndicatorState {
  40. // 刷新指示器颜色
  41. CGRect selectedCellFrame = CGRectZero;
  42. JXCategoryIndicatorCellModel *selectedCellModel = nil;
  43. for (int i = 0; i < self.dataSource.count; i++) {
  44. JXCategoryIndicatorCellModel *cellModel = (JXCategoryIndicatorCellModel *)self.dataSource[i];
  45. cellModel.sepratorLineShowEnabled = self.isSeparatorLineShowEnabled;
  46. cellModel.separatorLineColor = self.separatorLineColor;
  47. cellModel.separatorLineSize = self.separatorLineSize;
  48. cellModel.backgroundViewMaskFrame = CGRectZero;
  49. cellModel.cellBackgroundColorGradientEnabled = self.isCellBackgroundColorGradientEnabled;
  50. cellModel.cellBackgroundSelectedColor = self.cellBackgroundSelectedColor;
  51. cellModel.cellBackgroundUnselectedColor = self.cellBackgroundUnselectedColor;
  52. if (i == self.dataSource.count - 1) {
  53. cellModel.sepratorLineShowEnabled = NO;
  54. }
  55. if (i == self.selectedIndex) {
  56. selectedCellModel = cellModel;
  57. selectedCellFrame = [self getTargetCellFrame:i];
  58. }
  59. }
  60. for (UIView<JXCategoryIndicatorProtocol> *indicator in self.indicators) {
  61. if (self.dataSource.count <= 0) {
  62. indicator.hidden = YES;
  63. }else {
  64. indicator.hidden = NO;
  65. JXCategoryIndicatorParamsModel *indicatorParamsModel = [[JXCategoryIndicatorParamsModel alloc] init];
  66. indicatorParamsModel.selectedIndex = self.selectedIndex;
  67. indicatorParamsModel.selectedCellFrame = selectedCellFrame;
  68. [indicator jx_refreshState:indicatorParamsModel];
  69. }
  70. }
  71. }
  72. - (void)gk_refreshCellAndIndicatorState {
  73. [self gk_refreshCellState];
  74. [self gk_refreshIndicatorState];
  75. }
  76. #pragma mark - Override
  77. - (Class)preferredCellClass {
  78. return [JXCategoryTitleCell class];
  79. }
  80. - (void)refreshDataSource {
  81. NSInteger count = [self numberOfTitles];
  82. NSMutableArray *tempArray = [NSMutableArray arrayWithCapacity:count];
  83. for (int i = 0; i < count; i++) {
  84. JXCategoryTitleCellModel *cellModel = [[JXCategoryTitleCellModel alloc] init];
  85. [tempArray addObject:cellModel];
  86. }
  87. self.dataSource = [NSArray arrayWithArray:tempArray];
  88. }
  89. - (void)refreshSelectedCellModel:(JXCategoryBaseCellModel *)selectedCellModel unselectedCellModel:(JXCategoryBaseCellModel *)unselectedCellModel {
  90. [super refreshSelectedCellModel:selectedCellModel unselectedCellModel:unselectedCellModel];
  91. JXCategoryTitleCellModel *myUnselectedCellModel = (JXCategoryTitleCellModel *)unselectedCellModel;
  92. JXCategoryTitleCellModel *myselectedCellModel = (JXCategoryTitleCellModel *)selectedCellModel;
  93. if (self.isSelectedAnimationEnabled && (selectedCellModel.selectedType == JXCategoryCellSelectedTypeClick || selectedCellModel.selectedType == JXCategoryCellSelectedTypeCode)) {
  94. //开启了动画过渡,且cell在屏幕内,current的属性值会在cell里面进行动画插值更新
  95. //1、当unselectedCell在屏幕外的时候,还是需要在这里更新值
  96. //2、当selectedCell在屏幕外的时候,还是需要在这里更新值(比如调用selectItemAtIndex方法选中的时候)
  97. BOOL isUnselectedCellVisible = NO;
  98. BOOL isSelectedCellVisible = NO;
  99. NSArray *indexPaths = [self.collectionView indexPathsForVisibleItems];
  100. for (NSIndexPath *indexPath in indexPaths) {
  101. if (indexPath.item == myUnselectedCellModel.index) {
  102. isUnselectedCellVisible = YES;
  103. continue;
  104. } else if (indexPath.item == myselectedCellModel.index) {
  105. isSelectedCellVisible = YES;
  106. continue;
  107. }
  108. }
  109. if (!isUnselectedCellVisible) {
  110. //但是当unselectedCell在屏幕外时,不会在cell里面通过动画插值更新,在这里直接更新
  111. myUnselectedCellModel.titleCurrentColor = myUnselectedCellModel.titleNormalColor;
  112. myUnselectedCellModel.titleLabelCurrentZoomScale = myUnselectedCellModel.titleLabelNormalZoomScale;
  113. myUnselectedCellModel.titleLabelCurrentStrokeWidth = myUnselectedCellModel.titleLabelNormalStrokeWidth;
  114. }
  115. if (!isSelectedCellVisible) {
  116. //但是当selectedCell在屏幕外时,不会在cell里面通过动画插值更新,在这里直接更新
  117. myselectedCellModel.titleCurrentColor = myselectedCellModel.titleSelectedColor;
  118. myselectedCellModel.titleLabelCurrentZoomScale = myselectedCellModel.titleLabelSelectedZoomScale;
  119. myselectedCellModel.titleLabelCurrentStrokeWidth = myselectedCellModel.titleLabelSelectedStrokeWidth;
  120. }
  121. } else {
  122. //没有开启动画,可以直接更新属性
  123. myselectedCellModel.titleCurrentColor = myselectedCellModel.titleSelectedColor;
  124. myselectedCellModel.titleLabelCurrentZoomScale = myselectedCellModel.titleLabelSelectedZoomScale;
  125. myselectedCellModel.titleLabelCurrentStrokeWidth = myselectedCellModel.titleLabelSelectedStrokeWidth;
  126. myUnselectedCellModel.titleCurrentColor = myUnselectedCellModel.titleNormalColor;
  127. myUnselectedCellModel.titleLabelCurrentZoomScale = myUnselectedCellModel.titleLabelNormalZoomScale;
  128. myUnselectedCellModel.titleLabelCurrentStrokeWidth = myUnselectedCellModel.titleLabelNormalStrokeWidth;
  129. }
  130. }
  131. - (void)refreshLeftCellModel:(JXCategoryBaseCellModel *)leftCellModel rightCellModel:(JXCategoryBaseCellModel *)rightCellModel ratio:(CGFloat)ratio {
  132. [super refreshLeftCellModel:leftCellModel rightCellModel:rightCellModel ratio:ratio];
  133. JXCategoryTitleCellModel *leftModel = (JXCategoryTitleCellModel *)leftCellModel;
  134. JXCategoryTitleCellModel *rightModel = (JXCategoryTitleCellModel *)rightCellModel;
  135. if (self.isTitleLabelZoomEnabled && self.isTitleLabelZoomScrollGradientEnabled) {
  136. leftModel.titleLabelCurrentZoomScale = [JXCategoryFactory interpolationFrom:self.titleLabelZoomScale to:1.0 percent:ratio];
  137. rightModel.titleLabelCurrentZoomScale = [JXCategoryFactory interpolationFrom:1.0 to:self.titleLabelZoomScale percent:ratio];
  138. }
  139. if (self.isTitleLabelStrokeWidthEnabled) {
  140. leftModel.titleLabelCurrentStrokeWidth = [JXCategoryFactory interpolationFrom:leftModel.titleLabelSelectedStrokeWidth to:leftModel.titleLabelNormalStrokeWidth percent:ratio];
  141. rightModel.titleLabelCurrentStrokeWidth = [JXCategoryFactory interpolationFrom:rightModel.titleLabelNormalStrokeWidth to:rightModel.titleLabelSelectedStrokeWidth percent:ratio];
  142. }
  143. if (self.isTitleColorGradientEnabled) {
  144. leftModel.titleCurrentColor = [JXCategoryFactory interpolationColorFrom:self.titleSelectedColor to:self.titleColor percent:ratio];
  145. rightModel.titleCurrentColor = [JXCategoryFactory interpolationColorFrom:self.titleColor to:self.titleSelectedColor percent:ratio];
  146. }
  147. }
  148. - (CGFloat)preferredCellWidthAtIndex:(NSInteger)index {
  149. if (self.cellWidth == JXCategoryViewAutomaticDimension) {
  150. if (self.titleDataSource && [self.titleDataSource respondsToSelector:@selector(categoryTitleView:widthForTitle:)]) {
  151. return [self.titleDataSource categoryTitleView:self widthForTitle:[self titleWithIndex:index]];
  152. } else {
  153. return ceilf([[self titleWithIndex:index] boundingRectWithSize:CGSizeMake(MAXFLOAT, self.bounds.size.height) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName : self.titleFont} context:nil].size.width);
  154. }
  155. } else {
  156. return self.cellWidth;
  157. }
  158. }
  159. - (void)refreshCellModel:(JXCategoryBaseCellModel *)cellModel index:(NSInteger)index {
  160. [super refreshCellModel:cellModel index:index];
  161. JXCategoryTitleCellModel *model = (JXCategoryTitleCellModel *)cellModel;
  162. model.title = [self titleWithIndex:index];
  163. model.titleNumberOfLines = self.titleNumberOfLines;
  164. model.titleFont = self.titleFont;
  165. model.titleSelectedFont = self.titleSelectedFont;
  166. model.titleNormalColor = self.titleColor;
  167. model.titleSelectedColor = self.titleSelectedColor;
  168. model.titleLabelMaskEnabled = self.isTitleLabelMaskEnabled;
  169. model.titleLabelZoomEnabled = self.isTitleLabelZoomEnabled;
  170. model.titleLabelNormalZoomScale = 1;
  171. model.titleLabelZoomSelectedVerticalOffset = self.titleLabelZoomSelectedVerticalOffset;
  172. model.titleLabelSelectedZoomScale = self.titleLabelZoomScale;
  173. model.titleLabelStrokeWidthEnabled = self.isTitleLabelStrokeWidthEnabled;
  174. model.titleLabelNormalStrokeWidth = 0;
  175. model.titleLabelSelectedStrokeWidth = self.titleLabelSelectedStrokeWidth;
  176. model.titleLabelVerticalOffset = self.titleLabelVerticalOffset;
  177. model.titleLabelAnchorPointStyle = self.titleLabelAnchorPointStyle;
  178. if (index == self.selectedIndex) {
  179. model.titleCurrentColor = model.titleSelectedColor;
  180. model.titleLabelCurrentZoomScale = model.titleLabelSelectedZoomScale;
  181. model.titleLabelCurrentStrokeWidth= model.titleLabelSelectedStrokeWidth;
  182. }else {
  183. model.titleCurrentColor = model.titleNormalColor;
  184. model.titleLabelCurrentZoomScale = model.titleLabelNormalZoomScale;
  185. model.titleLabelCurrentStrokeWidth = model.titleLabelNormalStrokeWidth;
  186. }
  187. }
  188. - (NSInteger)numberOfTitles {
  189. if ([self.titleDataSource respondsToSelector:@selector(numberOfTitleView:)] && [self.titleDataSource respondsToSelector:@selector(titleView:titleForIndex:)]) {
  190. return [self.titleDataSource numberOfTitleView:self];
  191. }
  192. return self.titles.count;
  193. }
  194. - (NSString *)titleWithIndex:(NSInteger)index {
  195. if ([self.titleDataSource respondsToSelector:@selector(numberOfTitleView:)] && [self.titleDataSource respondsToSelector:@selector(titleView:titleForIndex:)]) {
  196. return [self.titleDataSource titleView:self titleForIndex:index];
  197. }
  198. return self.titles[index];
  199. }
  200. @end