NYFailSpecialExerciseDetailsCell01.m 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. //
  2. // NYFailSpecialExerciseDetailsCell01.m
  3. // jiaPei
  4. //
  5. // Created by Ning.ge on 2024/12/17.
  6. // Copyright © 2024 JCZ. All rights reserved.
  7. //
  8. #import "NYFailSpecialExerciseDetailsCell01.h"
  9. @interface NYFailSpecialExerciseDetailsCell01 ()
  10. @property (nonatomic, readwrite, strong) NYFailSpecialExerciseDetailItemModel *viewModel;
  11. @end
  12. @implementation NYFailSpecialExerciseDetailsCell01
  13. #pragma mark - PublicMethods
  14. + (instancetype)cellWithCollectionView:(UICollectionView *)collectionView forIndexPath:(NSIndexPath *)indexPath {
  15. static NSString *ID = @"NYFailSpecialExerciseDetailsCell01";
  16. [collectionView registerNib:[UINib nibWithNibName:ID bundle:nil] forCellWithReuseIdentifier:ID];
  17. NYFailSpecialExerciseDetailsCell01 *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
  18. if (!cell) cell = [self rq_viewFromXib];
  19. return cell;
  20. }
  21. - (void)bindViewModel:(NYFailSpecialExerciseDetailItemModel *)viewModel {
  22. @weakify(self)
  23. self.viewModel = viewModel;
  24. self.scoreStr_label.text = viewModel.dataModel.title;
  25. self.vw_left_label.text = viewModel.itemPointTitle;
  26. __block CGFloat yOffset = 0; // 初始偏移量
  27. __block CGFloat cellHeight = 35.f; // 每个 Cell 的高度(根据实际设计调整)
  28. int bi = 0;
  29. CGFloat imgW = (RQ_SCREEN_WIDTH-22*2);
  30. self.itop_view.hidden = YES;
  31. if(viewModel.dataModel.con.count>0){//手势
  32. for (int i= 0; i<viewModel.dataModel.con.count; i++) {
  33. NYFailItemPointDataCon *con = viewModel.dataModel.con[i];
  34. NSString *img_url = con.image;
  35. UIImageView *image_view = [self.item_view viewWithTag:99+i];
  36. __block CGSize imageSize = CGSizeMake(imgW,cellHeight);
  37. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  38. // 处理耗时操作的代码块...
  39. imageSize = [UIImage getImageSizeWithURL:img_url];
  40. //通知主线程刷新
  41. dispatch_async(dispatch_get_main_queue(), ^{
  42. //回调或者说是通知主线程刷新,
  43. if (imageSize.width == 0 || imageSize.height == 0) {
  44. cellHeight = imgW * (175.f / 345.f);
  45. } else {
  46. cellHeight = imgW * (imageSize.height / imageSize.width);
  47. }
  48. image_view.frame = CGRectMake(0, yOffset, imgW, cellHeight);
  49. // 调整偏移量
  50. yOffset += cellHeight+10*(i+1);
  51. });
  52. });
  53. [image_view sd_setImageWithURL:[NSURL URLWithString:img_url]];
  54. image_view.hidden = NO;
  55. bi = i+1;
  56. }
  57. for (int ci=bi; ci<10; ci++) {
  58. UIImageView *image_view = [self.item_view viewWithTag:99+ci];
  59. image_view.hidden = YES;
  60. }
  61. }
  62. if(viewModel.dataModel.tagquestions.count>0){
  63. self.vw_left_view.hidden = YES;
  64. self.itop_view.hidden = NO;
  65. self.itop_view.frame = CGRectMake(0, 0, imgW, viewModel.dataModel.iviewH);
  66. CGFloat tagitop_yOffset = 10; // 初始偏移量
  67. CGFloat tagtop_cellHeight = 35.f; // 每个 Cell 的高度(根据实际设计调整)
  68. int tagitop_bi = 0;
  69. int tagitop_bicc = 0;
  70. int tagitop_biccc = 0;
  71. for (int i= 0; i<viewModel.dataModel.tagquestions.count; i++) {
  72. NYFailItemPointDataQuestions *tag = viewModel.dataModel.tagquestions[i];
  73. NSString *tag_str = tag.tag;
  74. // 从 XIB 加载 NYFailItemPointCellView
  75. UIButton *btn = [self.itop_view viewWithTag:29+i];
  76. btn.hidden = NO;
  77. btn.frame = CGRectMake(10, tagitop_yOffset+10*i, 150.f, 25.f);
  78. [btn setTitleNormal:tag_str];
  79. // 调整偏移量
  80. tagitop_yOffset += 25.f+10*i;
  81. for (int z= 0; z<tag.tagCon.count; z++) {
  82. NYFailItemPointDataQuesTexts *textItem = tag.tagCon[z];
  83. NSString *title_str = textItem.subTitle;
  84. // 从 XIB 加载 NYFailItemPointCellView
  85. NYFailItemPointCellView *cellView = [self.itop_view viewWithTag:19+z+tagitop_bicc];
  86. cellView.hidden = NO;
  87. CGSize str_size = [title_str rq_sizeWithFont:cellView.content_label.font limitWidth:cellView.content_label.width];
  88. if(str_size.height>tagtop_cellHeight){
  89. tagtop_cellHeight = str_size.height + 12.f;
  90. }
  91. cellView.frame = CGRectMake(0, tagitop_yOffset, RQ_SCREEN_WIDTH-22*2, tagtop_cellHeight);
  92. cellView.content_label.attributedText = [self getAttributedString:title_str color:UIColorHex(0xFF6714)];
  93. // 调整偏移量
  94. tagitop_yOffset += tagtop_cellHeight;
  95. if(textItem.quesItem.count>0){
  96. CGFloat ab_H = 20.f;
  97. for (int t= 0; t<textItem.quesItem.count; t++) {
  98. NSString *item_str = textItem.quesItem[t];
  99. UILabel *label = [self.itop_view viewWithTag:59+t+tagitop_biccc];
  100. label.hidden = NO;
  101. label.attributedText = [self getAttributedString:item_str color:UIColorHex(0xFF6714)];
  102. label.frame = CGRectMake(10, tagitop_yOffset, RQ_SCREEN_WIDTH-22*2, ab_H);
  103. tagitop_yOffset += ab_H;
  104. }
  105. tagitop_biccc += textItem.quesItem.count;
  106. }
  107. }
  108. tagitop_bicc += tag.tagCon.count;
  109. tagitop_bi =i+1;
  110. }
  111. for (int ci=tagitop_bi; ci<10; ci++) {
  112. UIButton *btn = [self.itop_view viewWithTag:29+ci];
  113. btn.hidden = YES;
  114. }
  115. for (int ci=tagitop_biccc; ci<10; ci++) {
  116. UILabel *label = [self.itop_view viewWithTag:59+ci];
  117. label.hidden = YES;
  118. }
  119. for (int ci=tagitop_bicc; ci<10; ci++) {
  120. NYFailItemPointCellView *cellView = [self.itop_view viewWithTag:19+ci];
  121. cellView.hidden = YES;
  122. }
  123. }
  124. if(viewModel.dataModel.iquestions.count>0){
  125. for (int i= 0; i<viewModel.dataModel.iquestions.count; i++) {
  126. NYFailItemPointDataQuesImage *img = viewModel.dataModel.iquestions[i];
  127. NSString *img_url = img.image;
  128. UIImageView *image_view = [self.item_view viewWithTag:99+i];
  129. __block CGSize imageSize = CGSizeMake(imgW,cellHeight);
  130. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  131. // 处理耗时操作的代码块...
  132. imageSize = [UIImage getImageSizeWithURL:img_url];
  133. //通知主线程刷新
  134. dispatch_async(dispatch_get_main_queue(), ^{
  135. //回调或者说是通知主线程刷新,
  136. if (imageSize.width == 0 || imageSize.height == 0) {
  137. cellHeight = imgW * (175.f / 345.f);
  138. } else {
  139. cellHeight = imgW * (imageSize.height / imageSize.width);
  140. }
  141. image_view.frame = CGRectMake(0, yOffset, imgW, cellHeight);
  142. // 调整偏移量
  143. yOffset += cellHeight+10*(i+1);
  144. });
  145. });
  146. [image_view sd_setImageWithURL:[NSURL URLWithString:img_url]];
  147. image_view.hidden = NO;
  148. bi = i+1;
  149. }
  150. for (int ci=bi; ci<10; ci++) {
  151. UIImageView *image_view = [self.item_view viewWithTag:99+ci];
  152. image_view.hidden = YES;
  153. }
  154. }
  155. if(viewModel.dataModel.fquestions.count>0){
  156. self.vw_left_view.hidden = YES;
  157. self.itop_view.hidden = NO;
  158. self.itop_view.frame = CGRectMake(0, 0, imgW, viewModel.dataModel.iviewH);
  159. yOffset = CGRectGetMaxY(self.itop_view.frame) +10.f;
  160. CGFloat fitop_yOffset = 0; // 初始偏移量
  161. CGFloat fitop_cellHeight = 35.f; // 每个 Cell 的高度(根据实际设计调整)
  162. int fitop_bi = 0;
  163. int fitop_bicc = 0;
  164. for (int i= 0; i<viewModel.dataModel.fquestions.count; i++) {
  165. NYFailItemPointDataQuesTexts *textItem = viewModel.dataModel.fquestions[i];
  166. NSString *title_str = textItem.subTitle;
  167. // 从 XIB 加载 NYFailItemPointCellView
  168. NYFailItemPointCellView *cellView = [self.itop_view viewWithTag:19+i];
  169. cellView.hidden = NO;
  170. CGSize str_size = [title_str rq_sizeWithFont:cellView.content_label.font limitWidth:cellView.content_label.width];
  171. if(str_size.height>fitop_cellHeight){
  172. fitop_cellHeight = str_size.height + 12.f;
  173. }
  174. cellView.frame = CGRectMake(0, fitop_yOffset, RQ_SCREEN_WIDTH-22*2, fitop_cellHeight);
  175. cellView.content_label.attributedText = [self getAttributedString:title_str color:UIColorHex(0xFF6714)];
  176. // 调整偏移量
  177. fitop_yOffset += fitop_cellHeight;
  178. fitop_bi = i+1;
  179. if(textItem.quesItem.count>0){
  180. CGFloat ab_H = 20.f;
  181. for (int z= 0; z<textItem.quesItem.count; z++) {
  182. NSString *item_str = textItem.quesItem[z];
  183. UILabel *label = [self.itop_view viewWithTag:59+z+fitop_bicc];
  184. label.hidden = NO;
  185. label.attributedText = [self getAttributedString:item_str color:UIColorHex(0xFF6714)];
  186. label.frame = CGRectMake(10, fitop_yOffset, RQ_SCREEN_WIDTH-22*2, ab_H);
  187. fitop_yOffset += ab_H;
  188. }
  189. fitop_bicc += textItem.quesItem.count;
  190. }
  191. }
  192. for (int ci=fitop_bicc; ci<10; ci++) {
  193. UILabel *label = [self.itop_view viewWithTag:59+ci];
  194. label.hidden = YES;
  195. }
  196. for (int ci=fitop_bi; ci<10; ci++) {
  197. NYFailItemPointCellView *cellView = [self.itop_view viewWithTag:19+ci];
  198. cellView.hidden = YES;
  199. }
  200. }
  201. if(viewModel.dataModel.questions.quesTexts.count>0){
  202. self.itop_view.hidden = NO;
  203. self.itop_view.frame = CGRectMake(0, 0, imgW, viewModel.dataModel.iviewH);
  204. yOffset = CGRectGetMaxY(self.itop_view.frame) +10.f;
  205. CGFloat itop_yOffset = 0; // 初始偏移量
  206. CGFloat itop_cellHeight = 35.f; // 每个 Cell 的高度(根据实际设计调整)
  207. int itop_bi = 0;
  208. int itop_bicc = 0;
  209. for (int i= 0; i<viewModel.dataModel.questions.quesTexts.count; i++) {
  210. NYFailItemPointDataQuesTexts *textItem = viewModel.dataModel.questions.quesTexts[i];
  211. NSString *title_str = textItem.subTitle;
  212. // 从 XIB 加载 NYFailItemPointCellView
  213. NYFailItemPointCellView *cellView = [self.itop_view viewWithTag:19+i];
  214. cellView.hidden = NO;
  215. CGSize str_size = [title_str rq_sizeWithFont:cellView.content_label.font limitWidth:cellView.content_label.width];
  216. if(str_size.height>itop_cellHeight){
  217. itop_cellHeight = str_size.height + 12.f;
  218. }
  219. cellView.frame = CGRectMake(0, itop_yOffset, RQ_SCREEN_WIDTH-22*2, itop_cellHeight);
  220. cellView.content_label.attributedText = [self getAttributedString:title_str color:UIColorHex(0xFF6714)];
  221. // 调整偏移量
  222. itop_yOffset += itop_cellHeight;
  223. itop_bi = i+1;
  224. if(textItem.quesItem.count>0){
  225. CGFloat ab_H = 20.f;
  226. for (int z= 0; z<textItem.quesItem.count; z++) {
  227. NSString *item_str = textItem.quesItem[z];
  228. UILabel *label = [self.itop_view viewWithTag:59+z+itop_bicc];
  229. label.hidden = NO;
  230. label.attributedText = [self getAttributedString:item_str color:UIColorHex(0xFF6714)];
  231. label.frame = CGRectMake(10, itop_yOffset, RQ_SCREEN_WIDTH-22*2, ab_H);
  232. itop_yOffset += ab_H;
  233. }
  234. itop_bicc += textItem.quesItem.count;
  235. }
  236. }
  237. for (int ci=itop_bicc; ci<10; ci++) {
  238. UILabel *label = [self.itop_view viewWithTag:59+ci];
  239. label.hidden = YES;
  240. }
  241. for (int ci=itop_bi; ci<10; ci++) {
  242. NYFailItemPointCellView *cellView = [self.itop_view viewWithTag:19+ci];
  243. cellView.hidden = YES;
  244. }
  245. }
  246. for (int i= 0; i<viewModel.dataModel.questions.images.count; i++) {
  247. NSString *img_url = viewModel.dataModel.questions.images[i];
  248. UIImageView *image_view = [self.item_view viewWithTag:99+i];
  249. __block CGSize imageSize = CGSizeMake(imgW,cellHeight);
  250. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  251. @strongify(self)
  252. // 处理耗时操作的代码块...
  253. imageSize = [UIImage getImageSizeWithURL:img_url];
  254. //通知主线程刷新
  255. dispatch_async(dispatch_get_main_queue(), ^{
  256. //回调或者说是通知主线程刷新,
  257. if (imageSize.width == 0 || imageSize.height == 0) {
  258. cellHeight = imgW * (175.f / 345.f);
  259. } else {
  260. cellHeight = imgW * (imageSize.height / imageSize.width);
  261. }
  262. image_view.frame = CGRectMake(0, yOffset, imgW, cellHeight);
  263. // 调整偏移量
  264. yOffset += cellHeight+10*(i+1);
  265. });
  266. });
  267. [image_view sd_setImageWithURL:[NSURL URLWithString:img_url]];
  268. image_view.hidden = NO;
  269. bi = i+1;
  270. for (int ci=bi; ci<10; ci++) {
  271. UIImageView *image_view = [self.item_view viewWithTag:99+ci];
  272. image_view.hidden = YES;
  273. }
  274. }
  275. }
  276. - (NSMutableAttributedString*)getAttributedString:(NSString *)str color:(UIColor*)color {
  277. // 使用正则表达式匹配所有 [ ] 中的内容
  278. NSError *error = nil;
  279. NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\[([^\\]]+)\\]" options:0 error:&error];
  280. if (error) {
  281. NSLog(@"正则表达式错误: %@", error.localizedDescription);
  282. return [[NSMutableAttributedString alloc] initWithString:str];
  283. }
  284. // 用于存储需要替换的内容和范围
  285. NSMutableArray<NSDictionary *> *replacements = [NSMutableArray array];
  286. // 匹配 [ ] 中的内容
  287. NSArray<NSTextCheckingResult *> *matches = [regex matchesInString:str options:0 range:NSMakeRange(0, str.length)];
  288. for (NSTextCheckingResult *match in matches) {
  289. if (match.numberOfRanges > 1) {
  290. // 提取 [ ] 内部的内容
  291. NSRange innerRange = [match rangeAtIndex:1];
  292. NSString *matchedText = [str substringWithRange:innerRange];
  293. // 保存替换内容和范围
  294. [replacements addObject:@{
  295. @"text": matchedText,
  296. @"range": [NSValue valueWithRange:match.range]
  297. }];
  298. }
  299. }
  300. // 创建可变字符串以进行替换
  301. NSMutableString *updatedString = [NSMutableString stringWithString:str];
  302. NSMutableArray<NSValue *> *highlightedRanges = [NSMutableArray array];
  303. NSInteger offset = 0;
  304. for (NSDictionary *replacement in replacements) {
  305. NSString *text = replacement[@"text"];
  306. NSRange range = [replacement[@"range"] rangeValue];
  307. // 调整范围以匹配当前字符串的变化
  308. range.location += offset;
  309. // 替换 [ ] 为其内部内容
  310. [updatedString replaceCharactersInRange:range withString:text];
  311. // 记录调整后的范围
  312. NSRange adjustedRange = NSMakeRange(range.location, text.length);
  313. [highlightedRanges addObject:[NSValue valueWithRange:adjustedRange]];
  314. // 更新偏移量
  315. offset += (text.length - range.length);
  316. }
  317. // 创建 NSMutableAttributedString
  318. NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:updatedString];
  319. // 设置高亮颜色(黄色)
  320. for (NSValue *rangeValue in highlightedRanges) {
  321. [attributedString addAttribute:NSForegroundColorAttributeName value:color range:rangeValue.rangeValue];
  322. }
  323. return attributedString;
  324. }
  325. - (IBAction)submit_clickdo:(UIButton *)sender {
  326. NSString *questionIds = self.viewModel.dataModel.questionIds;
  327. NSArray *arr = [[RQ_YDTQuestion_Module getQuestionWithExerciseType:RQExerciseType_Error_Special_List questionIds:questionIds].rac_sequence.signal map:^id _Nullable(RQYDTQuestionModel *ydtQuestionModel) {
  328. return [RQExerciseModel exerciseModelWithRQYDTQuestionModel:ydtQuestionModel];
  329. }].toArray;
  330. RQExerciseViewModel *exerciseViewModel = [[RQExerciseViewModel alloc] initWithServices:RQ_APPDELEGATE.services params:@{
  331. RQHomePageCarTypeKey : @(RQ_YDTQuestion_Module.carType),
  332. RQHomePageSubjectTypeKey : @(RQ_YDTQuestion_Module.subject),
  333. RQHomeSubPageTypeKey : @(RQHomeSubPageType_SequentialPractice),
  334. RQViewModelIDKey : @"标题",
  335. RQExerciseTypeKey : @(RQExerciseType_Error_Special_List),
  336. RQViewModelUtilKey : arr,
  337. }];
  338. [RQ_APPDELEGATE.services pushViewModel:exerciseViewModel animated:YES];
  339. }
  340. #pragma mark - SystemMethods
  341. - (void)awakeFromNib {
  342. [super awakeFromNib];
  343. [self initTbList_view];
  344. }
  345. - (void)initTbList_view{
  346. UIView *itop_view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, RQ_SCREEN_WIDTH-22*2, 20)];
  347. itop_view.backgroundColor = UIColor.whiteColor;
  348. itop_view.layer.cornerRadius = 5.f;
  349. itop_view.layer.masksToBounds = YES;
  350. itop_view.hidden = YES;
  351. [self.item_view addSubview:itop_view];
  352. self.itop_view = itop_view;
  353. //10 + 10
  354. for (int i= 0; i<10; i++) {
  355. UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
  356. [btn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
  357. btn.titleLabel.font = [UIFont systemFontOfSize:15.f];
  358. btn.backgroundColor = UIColorHex(0xC1D7FF);
  359. btn.layer.cornerRadius = 5.f;
  360. btn.layer.masksToBounds = YES;
  361. btn.tag = 29+i;
  362. btn.hidden = YES;
  363. [self.itop_view addSubview:btn];
  364. }
  365. for (int i= 0; i<10; i++) {
  366. NYFailItemPointCellView *cellView = [[NYFailItemPointCellView alloc] initWithFrame:CGRectMake(0, 0, RQ_SCREEN_WIDTH-22*2, 0)];
  367. cellView.tag = 19+i;
  368. cellView.hidden = YES;
  369. [self.itop_view addSubview:cellView];
  370. }
  371. for (int i= 0; i<10; i++) {
  372. UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, RQ_SCREEN_WIDTH-22*2, 0)];
  373. label.font = [UIFont systemFontOfSize:11.f];
  374. label.textColor = UIColorHex(0x5C6066);
  375. label.tag = 59+i;
  376. label.hidden = YES;
  377. [self.itop_view addSubview:label];
  378. }
  379. // 初始化按钮
  380. CGFloat yOffset = 0; // 初始偏移量
  381. CGFloat cellHeight = 1.f; // 每个 Cell 的高度(根据实际设计调整)
  382. for (int i= 0; i<10; i++) {
  383. UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, yOffset, RQ_SCREEN_WIDTH-22*2, cellHeight)];
  384. imageView.tag = 99+i;
  385. imageView.hidden = YES;
  386. // 添加到 tbList_view
  387. [self.item_view addSubview:imageView];
  388. // 调整偏移量
  389. yOffset += cellHeight;
  390. }
  391. }
  392. @end