MOBaseLevelView.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. //
  2. // MOBaseLevelView.m
  3. // MiMoLive
  4. //
  5. // Created by SuperC on 2025/1/7.
  6. //
  7. #import "MOBaseLevelView.h"
  8. #import <UIImageView+YYWebImage.h>
  9. #import <YYAnimatedImageView.h>
  10. #import <objc/runtime.h>
  11. @interface MOBaseLevelView ()
  12. @property (nonatomic, strong) UIImageView *levelImg;
  13. @property (nonatomic, strong) UILabel *levelLabel;
  14. @end
  15. @implementation MOBaseLevelView
  16. - (instancetype)init{
  17. self = [super init];
  18. if(self){
  19. [self setupUI];
  20. }
  21. return self;
  22. }
  23. - (instancetype)initWithFrame:(CGRect)frame{
  24. self = [super initWithFrame:frame];
  25. if(self){
  26. [self setupUI];
  27. }
  28. return self;
  29. }
  30. - (instancetype)initWithCoder:(NSCoder *)coder{
  31. self = [super initWithCoder:coder];
  32. if(self){
  33. [self setupUI];
  34. }
  35. return self;
  36. }
  37. - (void)setupUI{
  38. CGFloat levelWidth = MOLevelNormalWidth;
  39. CGFloat levelLabelX = 16.0;
  40. CGFloat levelLabexWidth = levelWidth - levelLabelX;
  41. self.backgroundColor = [UIColor clearColor];
  42. [self addSubview:self.levelImg];
  43. [self.levelImg mas_makeConstraints:^(MASConstraintMaker *make) {
  44. make.left.bottom.right.top.equalTo(self);
  45. }];
  46. self.levelLabel = [[UILabel alloc] initWithFrame:CGRectMake(levelLabelX, 0, levelLabexWidth, 16.0)];
  47. self.levelLabel.font = [MOTextTools poppinsExtraBoldFont:10.0];
  48. self.levelLabel.textColor = [UIColor whiteColor];
  49. self.levelLabel.textAlignment = NSTextAlignmentCenter;
  50. self.levelLabel.text = @" ";
  51. [self addSubview:self.levelLabel];
  52. [self.levelLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  53. make.left.equalTo(self).offset(levelLabelX);
  54. make.top.bottom.equalTo(self);
  55. make.right.equalTo(self).offset(0.0);
  56. }];
  57. }
  58. - (void)setLevelNum:(NSInteger)levelNum{
  59. if(levelNum == 0){
  60. levelNum = 1;
  61. }
  62. _levelNum = levelNum;
  63. NSArray *levelInfoArr = [MOSvgaSourceManage shareManager].allLevelSoureArr;
  64. MOStoreInfo *medalInfo;
  65. for (MOStoreInfo *object in levelInfoArr) {
  66. if(levelNum >= object.limit){
  67. medalInfo = object;
  68. break;
  69. }
  70. }
  71. WEAKSELF
  72. if(medalInfo.res.length > 0){
  73. NSURL *url = [NSURL URLWithString:medalInfo.res];
  74. [self.levelImg sd_setImageWithURL:url];
  75. }
  76. else{
  77. UIImage *levelImg = [MOTextTools createLevelImageViewWith:levelNum];
  78. [self.levelImg setImage:levelImg];
  79. }
  80. self.levelLabel.text = [NSString stringWithFormat:@"%zd",levelNum];
  81. if(levelNum >= 100){
  82. [self.levelLabel mas_updateConstraints:^(MASConstraintMaker *make) {
  83. make.right.equalTo(self).offset(-5.0);
  84. }];
  85. }
  86. else if (levelNum < 10){
  87. [self.levelLabel mas_updateConstraints:^(MASConstraintMaker *make) {
  88. make.right.equalTo(self).offset(-2.0);
  89. }];
  90. }
  91. else{
  92. [self.levelLabel mas_updateConstraints:^(MASConstraintMaker *make) {
  93. make.right.equalTo(self).offset(-2.0);
  94. }];
  95. }
  96. }
  97. - (UIImageView *)levelImg{
  98. if(!_levelImg){
  99. CGFloat levelWidth = MOLevelNormalWidth;
  100. _levelImg = [[UIImageView alloc] init];
  101. _levelImg.frame = CGRectMake(0.0, 0.0, levelWidth, 16.0);
  102. _levelImg.contentMode = UIViewContentModeScaleAspectFit;
  103. }
  104. return _levelImg;
  105. }
  106. #pragma mark - Public Methods
  107. + (void)setStyledTextForLabel:(UILabel *)label
  108. fullText:(NSString *)text
  109. targetText:(NSString *)targetText
  110. color:(UIColor *)color
  111. hasUnderline:(BOOL)hasUnderline {
  112. if (!label || !text || !targetText) {
  113. return;
  114. }
  115. NSMutableAttributedString *attributedString;
  116. // 检查是否已有富文本,如果有则在现有基础上修改,否则创建新的
  117. if (label.attributedText && label.attributedText.length > 0) {
  118. // 验证文本内容是否一致
  119. if ([label.attributedText.string isEqualToString:text]) {
  120. // 文本一致,在现有富文本基础上修改
  121. attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];
  122. } else {
  123. // 文本不一致,创建新的富文本
  124. attributedString = [[NSMutableAttributedString alloc] initWithString:text];
  125. // 设置整体文本样式
  126. [attributedString addAttribute:NSFontAttributeName
  127. value:[UIFont systemFontOfSize:14.0]
  128. range:NSMakeRange(0, text.length)];
  129. [attributedString addAttribute:NSForegroundColorAttributeName
  130. value:[UIColor blackColor]
  131. range:NSMakeRange(0, text.length)];
  132. }
  133. } else {
  134. // 没有现有富文本,创建新的
  135. attributedString = [[NSMutableAttributedString alloc] initWithString:text];
  136. // 设置整体文本样式
  137. [attributedString addAttribute:NSFontAttributeName
  138. value:[UIFont systemFontOfSize:14.0]
  139. range:NSMakeRange(0, text.length)];
  140. [attributedString addAttribute:NSForegroundColorAttributeName
  141. value:[UIColor blackColor]
  142. range:NSMakeRange(0, text.length)];
  143. }
  144. // 查找目标文本的位置
  145. NSRange targetRange = [attributedString.string rangeOfString:targetText];
  146. if (targetRange.location != NSNotFound) {
  147. // 设置目标文本颜色
  148. [attributedString addAttribute:NSForegroundColorAttributeName
  149. value:color
  150. range:targetRange];
  151. // 添加下划线(如果需要)
  152. if (hasUnderline) {
  153. [attributedString addAttribute:NSUnderlineStyleAttributeName
  154. value:@(NSUnderlineStyleSingle)
  155. range:targetRange];
  156. [attributedString addAttribute:NSUnderlineColorAttributeName
  157. value:color
  158. range:targetRange];
  159. } else {
  160. // 如果不需要下划线,移除可能存在的下划线样式
  161. [attributedString removeAttribute:NSUnderlineStyleAttributeName range:targetRange];
  162. [attributedString removeAttribute:NSUnderlineColorAttributeName range:targetRange];
  163. }
  164. // 存储目标文本范围信息(支持多个范围)
  165. NSMutableArray *ranges = objc_getAssociatedObject(label, @"targetRanges");
  166. if (!ranges) {
  167. ranges = [[NSMutableArray alloc] init];
  168. }
  169. [ranges addObject:[NSValue valueWithRange:targetRange]];
  170. objc_setAssociatedObject(label, @"targetRanges", ranges, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  171. }
  172. label.attributedText = attributedString;
  173. }
  174. + (void)addTapGestureToLabel:(UILabel *)label
  175. target:(id)target
  176. action:(SEL)action {
  177. if (!label || !target || !action) {
  178. return;
  179. }
  180. // 确保label可以接收用户交互
  181. label.userInteractionEnabled = YES;
  182. // 移除已存在的手势(避免重复添加)
  183. for (UIGestureRecognizer *gesture in label.gestureRecognizers) {
  184. if ([gesture isKindOfClass:[UITapGestureRecognizer class]]) {
  185. [label removeGestureRecognizer:gesture];
  186. }
  187. }
  188. // 添加点击手势
  189. UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:target action:action];
  190. [label addGestureRecognizer:tapGesture];
  191. // 存储相关信息
  192. objc_setAssociatedObject(label, @"target", target, OBJC_ASSOCIATION_ASSIGN);
  193. objc_setAssociatedObject(label, @"action", NSStringFromSelector(action), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  194. }
  195. + (void)setMultipleStyledTextForLabel:(UILabel *)label
  196. fullText:(NSString *)fullText
  197. styleConfigs:(NSArray<NSDictionary *> *)styleConfigs {
  198. if (!label || !fullText || !styleConfigs || styleConfigs.count == 0) {
  199. return;
  200. }
  201. // 创建初始富文本
  202. NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:fullText];
  203. // 设置整体文本样式
  204. [attributedString addAttribute:NSFontAttributeName
  205. value:[UIFont systemFontOfSize:14.0]
  206. range:NSMakeRange(0, fullText.length)];
  207. [attributedString addAttribute:NSForegroundColorAttributeName
  208. value:[UIColor blackColor]
  209. range:NSMakeRange(0, fullText.length)];
  210. NSMutableArray *ranges = [[NSMutableArray alloc] init];
  211. // 遍历所有样式配置
  212. for (NSDictionary *config in styleConfigs) {
  213. NSString *targetText = config[@"targetText"];
  214. UIColor *color = config[@"color"];
  215. NSNumber *hasUnderlineNum = config[@"hasUnderline"];
  216. if (!targetText || !color || !hasUnderlineNum) {
  217. continue; // 跳过无效配置
  218. }
  219. BOOL hasUnderline = [hasUnderlineNum boolValue];
  220. // 查找目标文本的位置
  221. NSRange targetRange = [fullText rangeOfString:targetText];
  222. if (targetRange.location != NSNotFound) {
  223. // 设置目标文本颜色
  224. [attributedString addAttribute:NSForegroundColorAttributeName
  225. value:color
  226. range:targetRange];
  227. // 添加或移除下划线
  228. if (hasUnderline) {
  229. [attributedString addAttribute:NSUnderlineStyleAttributeName
  230. value:@(NSUnderlineStyleSingle)
  231. range:targetRange];
  232. [attributedString addAttribute:NSUnderlineColorAttributeName
  233. value:color
  234. range:targetRange];
  235. } else {
  236. [attributedString removeAttribute:NSUnderlineStyleAttributeName range:targetRange];
  237. [attributedString removeAttribute:NSUnderlineColorAttributeName range:targetRange];
  238. }
  239. // 收集范围信息
  240. [ranges addObject:[NSValue valueWithRange:targetRange]];
  241. }
  242. }
  243. // 存储所有范围信息
  244. objc_setAssociatedObject(label, @"targetRanges", ranges, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  245. // 设置富文本
  246. label.attributedText = attributedString;
  247. }
  248. + (UILabel *)createFeedbackLabelWithText:(NSString *)text
  249. feedbackText:(NSString *)feedbackText
  250. target:(id)target
  251. action:(SEL)action {
  252. UILabel *label = [[UILabel alloc] init];
  253. label.numberOfLines = 0;
  254. // 使用新的分离方法设置样式
  255. [self setStyledTextForLabel:label
  256. fullText:text
  257. targetText:feedbackText
  258. color:[UIColor blueColor]
  259. hasUnderline:YES];
  260. // 使用新的分离方法添加点击事件
  261. [self addTapGestureToLabel:label target:target action:action];
  262. return label;
  263. }
  264. @end