RQExerciseQuestionItemViewModel.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. //
  2. // RQExerciseQuestionItemViewModel.m
  3. // SDJK
  4. //
  5. // Created by 张嵘 on 2021/8/16.
  6. //
  7. #import "RQExerciseQuestionItemViewModel.h"
  8. #import "XHWebImageAutoSize.h"
  9. @interface RQExerciseQuestionItemViewModel ()
  10. @property (nonatomic, readwrite, strong) RQExerciseModel *exerciseModel;
  11. @property (nonatomic, readwrite, strong) YYLabel *yyLabel;
  12. @property (nonatomic, readwrite, strong) NSString *typeString;
  13. @property (nonatomic, readwrite, strong) NSString *newString;
  14. @property (nonatomic, readwrite, strong) NSMutableAttributedString *qusetionString;
  15. @property (nonatomic, readwrite, assign) CGFloat labelHeight;
  16. @property (nonatomic, readwrite, assign) CGFloat imageHeight;
  17. @property (nonatomic, readwrite, strong) NSString *imageString;
  18. @property (nonatomic, readwrite, strong) NSString *videoString;
  19. @property (nonatomic, readwrite, strong) NSMutableAttributedString *spaceAttachment;
  20. @end
  21. @implementation RQExerciseQuestionItemViewModel
  22. - (instancetype)initWithRQExerciseModel:(RQExerciseModel *)exerciseModel {
  23. if (self = [super init]) {
  24. self.exerciseModel = exerciseModel;
  25. if ([exerciseModel.answer containsString:@"-"]) {
  26. self.typeString = @"多选题";
  27. } else if ([exerciseModel.answer containsString:@"√"] || [exerciseModel.answer containsString:@"×"]) {
  28. self.typeString = @"判断题";
  29. } else {
  30. self.typeString = @"单选题";
  31. }
  32. NSString *questionStr = [NSString stringWithFormat:@"%ld、%@",(long)exerciseModel.num + 1,exerciseModel.issue];
  33. NSMutableAttributedString *text = [NSMutableAttributedString new];
  34. NSMutableAttributedString *testText = [NSMutableAttributedString new];
  35. NSMutableAttributedString *typeAttachment = nil;
  36. QMUIButton *typeBtn = [QMUIButton buttonWithType:UIButtonTypeCustom];
  37. CGFloat btnHeight = (25.f / 17.f) * RQ_Exercise_Module.exerciseFontSize;
  38. CGFloat btnWeight = (60.f / 25.f) * btnHeight;
  39. CGFloat btnCornerRadius = btnHeight / 2.f;
  40. CGSize btnSize = CGSizeMake(btnWeight, btnHeight);
  41. typeBtn.size = btnSize;
  42. [typeBtn setTitle:self.typeString textColor:RQ_MAIN_TEXT_COLOR_WHITE Font:RQ_Exercise_Module.exerciseFontSize - 3 fotState:UIControlStateNormal];
  43. [typeBtn setBackgroundImage:[UIImage qmui_imageWithColor:RQ_MAIN_COLOR size:btnSize cornerRadiusArray:@[@(btnCornerRadius), @(btnCornerRadius), @0, @(btnCornerRadius)]] forState:UIControlStateNormal];
  44. typeAttachment = [NSMutableAttributedString yy_attachmentStringWithContent:typeBtn
  45. contentMode:UIViewContentModeCenter
  46. attachmentSize:btnSize
  47. alignToFont:[UIFont systemFontOfSize:RQ_Exercise_Module.exerciseFontSize]
  48. alignment:YYTextVerticalAlignmentCenter];
  49. [testText appendAttributedString:typeAttachment];
  50. [testText appendAttributedString:self.spaceAttachment];
  51. if (exerciseModel.is_new) {
  52. NSMutableAttributedString *newAttachment = nil;
  53. QMUIButton *newBtn = [QMUIButton buttonWithType:UIButtonTypeCustom];
  54. newBtn.size = btnSize;
  55. [newBtn setTitle:@"新规题" textColor:RQ_MAIN_TEXT_COLOR_WHITE Font:RQ_Exercise_Module.exerciseFontSize - 3 fotState:UIControlStateNormal];
  56. [newBtn setBackgroundImage:[UIImage qmui_imageWithColor:RQColorFromHexString(@"#9C5FED") size:btnSize cornerRadiusArray:@[@(btnCornerRadius), @(btnCornerRadius), @(btnCornerRadius), @(btnCornerRadius)]] forState:UIControlStateNormal];
  57. newAttachment = [NSMutableAttributedString yy_attachmentStringWithContent:newBtn
  58. contentMode:UIViewContentModeCenter
  59. attachmentSize:btnSize
  60. alignToFont:[UIFont systemFontOfSize:RQ_Exercise_Module.exerciseFontSize]
  61. alignment:YYTextVerticalAlignmentCenter];
  62. [testText appendAttributedString:newAttachment];
  63. [testText appendAttributedString:self.spaceAttachment];
  64. }
  65. NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:questionStr];
  66. attrString.yy_font = [UIFont systemFontOfSize:RQ_Exercise_Module.exerciseFontSize];
  67. attrString.yy_color = RQ_MAIN_TEXT_COLOR_1;
  68. if (RQStringIsNotEmpty(exerciseModel.titlekeyword) && exerciseModel.isShowSkillExplanation) {
  69. [[[exerciseModel.titlekeyword componentsSeparatedByString:@"-"].rac_sequence.signal deliverOnMainThread] subscribeNext:^(NSString * _Nullable skillkeywordStr) {
  70. NSRange range = [questionStr rangeOfString:skillkeywordStr];
  71. [attrString yy_setColor:RQ_MAIN_TEXT_COLOR_RED range:range];
  72. [attrString yy_setFont:[UIFont boldSystemFontOfSize:RQ_Exercise_Module.exerciseFontSize + 2] range:range];
  73. }];
  74. }
  75. // NSRange range = [string rangeOfString:@"《遵守实验室须知》"];
  76. // [attrString yy_setColor:[UIColor colorWithHexString:@"#19ADA9"] range:range];
  77. //
  78. // [attrString yy_setTextHighlightRange:range
  79. // color:[UIColor colorWithHexString:@"#19ADA9"]
  80. // backgroundColor:[UIColor blueColor]
  81. // tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
  82. // [_self showMessage:[NSString stringWithFormat:@"Tap: %@",[text.string substringWithRange:range]]];
  83. // }];
  84. [testText appendAttributedString: attrString];
  85. [text appendAttributedString:testText];
  86. // [text appendAttributedString:[self padding]];
  87. text.yy_lineSpacing = 8;
  88. self.qusetionString = text;
  89. self.labelHeight = [self getMessageHeightWithAttributedStr:text andLabel:self.yyLabel];
  90. self.imageString = exerciseModel.image;
  91. self.videoString = @"";
  92. if (RQStringIsNotEmpty(self.imageString)) {
  93. NSString *cacheKeyStr = [[YYWebImageManager sharedManager] cacheKeyForURL:[NSURL URLWithString:self.imageString]];
  94. UIImage *cacheImage = [[YYImageCache sharedCache] getImageForKey:cacheKeyStr];
  95. CGSize imageSize;
  96. if (cacheImage) {
  97. imageSize = cacheImage.size;
  98. } else {
  99. imageSize = [UIImage getImageSizeWithURL:self.imageString];
  100. }
  101. if (imageSize.width == 0 || imageSize.height == 0) {
  102. self.imageHeight = (RQ_SCREEN_WIDTH - 32.f) * (175.f / 345.f);
  103. } else {
  104. self.imageHeight = (RQ_SCREEN_WIDTH - 32.f) * (imageSize.height / imageSize.width);
  105. }
  106. self.rowHeight = 16.f + self.labelHeight + 16.f + self.imageHeight + 16.f;
  107. } else {
  108. self.rowHeight = 16.f + self.labelHeight + 16.f;
  109. }
  110. // 预选Option
  111. // NSString *questionStr = [NSString stringWithFormat:@"%ld、%@",(long)exerciseModel.num + 1,exerciseModel.issue];
  112. // self.qusetionString = [[NSMutableAttributedString alloc] initWithString:questionStr];
  113. // NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
  114. // [paragraphStyle setFirstLineHeadIndent:68];//首行缩进
  115. // [paragraphStyle setLineSpacing:10];//调整行间距
  116. // [_qusetionString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [questionStr length])];
  117. //
  118. // if (RQStringIsNotEmpty(exerciseModel.titlekeyword) && exerciseModel.isShowSkillExplanation) {
  119. // [[[exerciseModel.titlekeyword componentsSeparatedByString:@"-"].rac_sequence.signal deliverOnMainThread] subscribeNext:^(NSString * _Nullable skillkeywordStr) {
  120. // NSRange targetRange = NSMakeRange(0, questionStr.length);
  121. // NSRange range = targetRange;
  122. // while (true) {
  123. // range = [questionStr rangeOfString:skillkeywordStr options:NSLiteralSearch range:targetRange];
  124. //
  125. // if (range.location != NSNotFound) {
  126. // NSRange newRange = NSMakeRange(range.location - 1, range.length + 2);
  127. // if (newRange.length + newRange.location > range.location + range.length) {
  128. // NSInteger a = (newRange.length + newRange.location) - (range.location + range.length);
  129. // newRange = NSMakeRange(newRange.location - a, newRange.length);
  130. // }
  131. // NSString *keywordStr = [questionStr substringWithRange:newRange];
  132. // if ([keywordStr containsString:@"“"] || [keywordStr containsString:@"”"] || [keywordStr containsString:@"\""]) {
  133. // range = newRange;
  134. // }
  135. // targetRange = NSMakeRange(NSMaxRange(range), questionStr.length-NSMaxRange(range));
  136. //
  137. // [_qusetionString addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:RQ_Exercise_Module.exerciseFontSize + 2] range:range];
  138. // [_qusetionString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:RQ_Exercise_Module.exerciseFontSize] range:targetRange];
  139. // [_qusetionString addAttribute:NSForegroundColorAttributeName value:RQ_MAIN_TEXT_COLOR_RED range:range];
  140. //
  141. // } else {
  142. // break;
  143. // }
  144. // }
  145. //
  146. // } completed:^{
  147. // NSMutableAttributedString *caculateStr = [[NSMutableAttributedString alloc] initWithAttributedString:_qusetionString];
  148. // [caculateStr appendAttributedString:[[NSMutableAttributedString alloc] initWithString:_typeString]];
  149. // CGFloat yyHeight = [caculateStr.string heightForFont:[UIFont boldSystemFontOfSize:RQ_Exercise_Module.exerciseFontSize] width:RQ_SCREEN_WIDTH - (16 * 2)];
  150. // NSInteger lineNum = [self needLinesWithText:caculateStr.string width:RQ_SCREEN_WIDTH - (16 * 2)];
  151. // CGFloat labelHeight = yyHeight + (lineNum > 1? lineNum - 1 : 0) * 10;
  152. // self.imageString = exerciseModel.image;
  153. // self.videoString = @"";
  154. //
  155. // if (RQStringIsEmpty(_imageString)) {
  156. // self.rowHeight = labelHeight + (16 * 2);
  157. // } else {
  158. // self.rowHeight = labelHeight + (RQ_SCREEN_WIDTH - 32) * 0.4 + (16 * 3);
  159. // }
  160. // }];
  161. //
  162. // } else {
  163. // NSMutableAttributedString *caculateStr = [[NSMutableAttributedString alloc] initWithAttributedString:_qusetionString];
  164. // [caculateStr appendAttributedString:[[NSMutableAttributedString alloc] initWithString:_typeString]];
  165. // if (exerciseModel.is_new) {
  166. // [caculateStr appendAttributedString:[[NSMutableAttributedString alloc] initWithString:self.newString]];
  167. // }
  168. // CGFloat yyHeight = [caculateStr.string heightForFont:[UIFont boldSystemFontOfSize:RQ_Exercise_Module.exerciseFontSize] width:RQ_SCREEN_WIDTH - (16 * 2)];
  169. // NSInteger lineNum = [self needLinesWithText:caculateStr.string width:RQ_SCREEN_WIDTH - (16 * 2)];
  170. // CGFloat labelHeight = yyHeight + (lineNum > 1? lineNum - 1 : 0) * 10;
  171. // self.imageString = exerciseModel.image;
  172. // self.videoString = @"";
  173. //
  174. // if (RQStringIsEmpty(_imageString)) {
  175. // self.rowHeight = labelHeight + (16 * 2);
  176. // } else {
  177. // self.rowHeight = labelHeight + (RQ_SCREEN_WIDTH - 32) * 0.4 + (16 * 3);
  178. // }
  179. // }
  180. }
  181. return self;
  182. }
  183. /**
  184. 显示当前文字需要几行
  185. @param width 给定一个宽度
  186. @return 返回行数
  187. */
  188. - (NSInteger)needLinesWithText:(NSString *)textStr width:(CGFloat)width {
  189. //创建一个labe
  190. UILabel * label = [[UILabel alloc]init];
  191. //font和当前label保持一致
  192. label.font = [UIFont boldSystemFontOfSize:RQ_Exercise_Module.exerciseFontSize];
  193. NSString * text = textStr;
  194. NSInteger sum = 0;
  195. //总行数受换行符影响,所以这里计算总行数,需要用换行符分隔这段文字,然后计算每段文字的行数,相加即是总行数。
  196. NSArray * splitText = [text componentsSeparatedByString:@"\n"];
  197. for (NSString * sText in splitText) {
  198. label.text = sText;
  199. //获取这段文字一行需要的size
  200. CGSize textSize = [label systemLayoutSizeFittingSize:CGSizeZero];
  201. //size.width/所需要的width 向上取整就是这段文字占的行数
  202. NSInteger lines = ceilf(textSize.width/width);
  203. //当是0的时候,说明这是换行,需要按一行算。
  204. lines = lines == 0?1:lines;
  205. sum += lines;
  206. }
  207. return sum;
  208. }
  209. - (NSString *)newString {
  210. return @"新规题";
  211. }
  212. /**
  213. * 获取lb的高度
  214. * @param mess lb.text
  215. * @param lb (YYLabel *)label
  216. * @return lb的高度
  217. */
  218. - (CGFloat)getMessageHeight:(NSString *)mess andLabel:(YYLabel *)lb {
  219. NSMutableAttributedString *introText = [[NSMutableAttributedString alloc] initWithString:mess];
  220. introText.yy_font = [UIFont boldSystemFontOfSize:RQ_Exercise_Module.exerciseFontSize];
  221. introText.yy_lineSpacing = 8;
  222. lb.attributedText = introText;
  223. CGSize introSize = CGSizeMake(RQ_SCREEN_WIDTH - (16 * 2), CGFLOAT_MAX);
  224. YYTextLayout *layout = [YYTextLayout layoutWithContainerSize:introSize text:introText];
  225. lb.textLayout = layout;
  226. CGFloat introHeight = layout.textBoundingSize.height;
  227. return introHeight;
  228. }
  229. - (CGFloat)getMessageHeightWithAttributedStr:(NSMutableAttributedString *)attributedStr andLabel:(YYLabel *)lb {
  230. lb.attributedText = attributedStr;
  231. CGSize introSize = CGSizeMake(RQ_SCREEN_WIDTH - (16 * 2), CGFLOAT_MAX);
  232. YYTextLayout *layout = [YYTextLayout layoutWithContainerSize:introSize text:attributedStr];
  233. lb.textLayout = layout;
  234. CGFloat introHeight = layout.textBoundingSize.height;
  235. return introHeight;
  236. }
  237. - (YYLabel *)yyLabel {
  238. if (!_yyLabel) {
  239. _yyLabel = [[YYLabel alloc] init];
  240. }
  241. return _yyLabel;
  242. }
  243. - (NSMutableAttributedString *)spaceAttachment {
  244. if (!_spaceAttachment) {
  245. UIView *spaceView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 4, 25)];
  246. _spaceAttachment = [NSMutableAttributedString yy_attachmentStringWithContent:spaceView contentMode:UIViewContentModeCenter attachmentSize:CGSizeMake(4, 25) alignToFont:[UIFont boldSystemFontOfSize:RQ_Exercise_Module.exerciseFontSize] alignment:YYTextVerticalAlignmentCenter];
  247. }
  248. return _spaceAttachment;
  249. }
  250. - (NSString *)itemClassName {
  251. return @"RQExerciseQuestionCell";
  252. }
  253. @end