TUIJoinGroupMessageCell.m 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Created by Tencent on 2023/06/09.
  2. // Copyright © 2023 Tencent. All rights reserved.
  3. #import "TUIJoinGroupMessageCell.h"
  4. #import <TIMCommon/TIMDefine.h>
  5. @interface TUIJoinGroupMessageCell () <UITextViewDelegate>
  6. @property(nonatomic, strong) UITextView *textView;
  7. @end
  8. @implementation TUIJoinGroupMessageCell
  9. - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
  10. self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
  11. if (self) {
  12. _textView = [[UITextView alloc] init];
  13. _textView.editable = NO;
  14. _textView.scrollEnabled = NO;
  15. _textView.backgroundColor = [UIColor clearColor];
  16. _textView.textColor = [UIColor d_systemGrayColor];
  17. _textView.textContainerInset = UIEdgeInsetsMake(5, 0, 5, 0);
  18. _textView.layer.cornerRadius = 3;
  19. _textView.delegate = self;
  20. _textView.textAlignment = NSTextAlignmentLeft;
  21. [self.messageLabel removeFromSuperview];
  22. [self.container addSubview:_textView];
  23. _textView.delaysContentTouches = NO;
  24. }
  25. return self;
  26. }
  27. - (void)fillWithData:(TUIJoinGroupMessageCellData *)data;
  28. {
  29. [super fillWithData:data];
  30. self.joinData = data;
  31. self.nameLabel.hidden = YES;
  32. self.avatarView.hidden = YES;
  33. self.retryView.hidden = YES;
  34. [self.indicator stopAnimating];
  35. NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@", data.content]];
  36. NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
  37. paragraphStyle.alignment = NSTextAlignmentCenter;
  38. NSDictionary *attributeDict = @{
  39. NSFontAttributeName : self.messageLabel.font,
  40. NSForegroundColorAttributeName : [UIColor d_systemGrayColor],
  41. NSParagraphStyleAttributeName : paragraphStyle
  42. };
  43. [attributeString setAttributes:attributeDict range:NSMakeRange(0, attributeString.length)];
  44. if (data.userNameList.count > 0) {
  45. NSArray *nameRangeList = [self findRightRangeOfAllString:data.userNameList inText:attributeString.string];
  46. int i = 0;
  47. for (i = 0; i < nameRangeList.count; i++) {
  48. NSString *nameRangeString = nameRangeList[i];
  49. NSRange nameRange = NSRangeFromString(nameRangeString);
  50. [attributeString addAttribute:NSLinkAttributeName value:[NSString stringWithFormat:@"%d", i] range:nameRange];
  51. }
  52. }
  53. self.textView.attributedText = attributeString;
  54. // tell constraints they need updating
  55. [self setNeedsUpdateConstraints];
  56. // update constraints now so we can animate the change
  57. [self updateConstraintsIfNeeded];
  58. [self layoutIfNeeded];
  59. }
  60. + (BOOL)requiresConstraintBasedLayout {
  61. return YES;
  62. }
  63. // this is Apple's recommended place for adding/updating constraints
  64. - (void)updateConstraints {
  65. [super updateConstraints];
  66. [self.container mas_remakeConstraints:^(MASConstraintMaker *make) {
  67. make.center.mas_equalTo(self.contentView);
  68. make.size.mas_equalTo(self.contentView);
  69. }];
  70. if(self.textView.superview) {
  71. [self.textView mas_remakeConstraints:^(MASConstraintMaker *make) {
  72. make.center.mas_equalTo(self.container);
  73. make.size.mas_equalTo(self.contentView);
  74. }];
  75. }
  76. }
  77. - (void)layoutSubviews {
  78. [super layoutSubviews];
  79. self.container.tui_mm_center();
  80. self.textView.mm_fill();
  81. }
  82. - (void)onSelectUserName:(NSInteger)index {
  83. if (self.joinGroupDelegate && [self.joinGroupDelegate respondsToSelector:@selector(didTapOnRestNameLabel:withIndex:)])
  84. [self.joinGroupDelegate didTapOnRestNameLabel:self withIndex:index];
  85. }
  86. - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
  87. NSArray *userNames = _joinData.userNameList;
  88. NSURL *urlRecognizer = [[NSURL alloc] init];
  89. for (int i = 0; i < userNames.count; i++) {
  90. urlRecognizer = [NSURL URLWithString:[NSString stringWithFormat:@"%d", i]];
  91. if ([URL isEqual:urlRecognizer]) {
  92. [self onSelectUserName:i];
  93. }
  94. }
  95. return NO;
  96. }
  97. /**
  98. * To obtain the exact position of the nickname in the text content, the following properties are used: the storage order of userName in the array must be the
  99. * same as the order in which the final text is displayed. For example: the text content is, "A invited B, C, D to join the group", then the storage order of
  100. * the elements in userName must be ABCD. Therefore, the method of "searching from the beginning and searching in succession" is used. For example, find the
  101. * first element A first, because of the characteristics of rangeOfString, it must find the A at the head position. After finding A at the head position, we
  102. * remove A from the search range, and the search range becomes "B, C, D are invited to join the group", and then continue to search for the next element, which
  103. * is B.
  104. */
  105. - (NSMutableArray *)findRightRangeOfAllString:(NSMutableArray<NSString *> *)stringList inText:(NSString *)text {
  106. NSMutableArray *rangeList = [NSMutableArray array];
  107. NSUInteger beginLocation = 0;
  108. NSEnumerator *enumer = [stringList objectEnumerator];
  109. NSString *string = [NSString string];
  110. while (string = [enumer nextObject]) {
  111. NSRange newRange = NSMakeRange(beginLocation, text.length - beginLocation);
  112. NSRange stringRange = [text rangeOfString:string options:NSLiteralSearch range:newRange];
  113. if (stringRange.length > 0) {
  114. [rangeList addObject:NSStringFromRange(stringRange)];
  115. beginLocation = stringRange.location + stringRange.length;
  116. }
  117. }
  118. return rangeList;
  119. }
  120. @end