NSAttributedString+MLLabel.m 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. //
  2. // NSAttributedString+MLLabel.m
  3. // Pods
  4. //
  5. // Created by molon on 15/6/13.
  6. //
  7. //
  8. #import "NSAttributedString+MLLabel.h"
  9. @implementation NSAttributedString (MLLabel)
  10. + (instancetype)attributedStringWithHTML:(NSString*)htmlString
  11. {
  12. NSData* htmlData = [htmlString dataUsingEncoding:NSUTF8StringEncoding];
  13. if (htmlData) {
  14. __block id attributedString = nil;
  15. dispatch_block_t block = ^{
  16. attributedString = [[self alloc] initWithData:htmlData
  17. options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
  18. NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)}
  19. documentAttributes:nil
  20. error:NULL];
  21. };
  22. //这个解析必须在主线程执行,文档上要求的
  23. if ([NSThread isMainThread]) {
  24. block();
  25. }else{
  26. dispatch_sync(dispatch_get_main_queue(), block);
  27. }
  28. return attributedString;
  29. }
  30. return nil;
  31. }
  32. - (NSAttributedString*)linkAttributedStringWithLinkRegex:(NSRegularExpression*)linkRegex groupIndexForDisplay:(NSInteger)groupIndexForDisplay groupIndexForValue:(NSInteger)groupIndexForValue {
  33. NSParameterAssert(linkRegex);
  34. NSAssert(groupIndexForDisplay>0&&groupIndexForValue>0, @"groupIndexForDisplay and groupIndexForValue must >0!");
  35. NSInteger length = [self length];
  36. if (length<=0) {
  37. return self;
  38. }
  39. NSMutableAttributedString *resultAttributedString = [NSMutableAttributedString new];
  40. //正则匹配所有内容
  41. NSArray *results = [linkRegex matchesInString:self.string
  42. options:NSMatchingWithTransparentBounds
  43. range:NSMakeRange(0, length)];
  44. //遍历结果,找到结果中被()包裹的区域作为显示内容
  45. NSUInteger location = 0;
  46. for (NSTextCheckingResult *result in results) {
  47. NSAssert([result numberOfRanges]>1&&[result numberOfRanges]>groupIndexForDisplay&&[result numberOfRanges]>groupIndexForValue, @"Please ensure that group sign `()` in the linkRegex is correct!");
  48. NSRange range = [result rangeAtIndex:0];
  49. //把前面的非匹配出来的区域加进来
  50. NSAttributedString *subAttrStr = [self attributedSubstringFromRange:NSMakeRange(location, range.location - location)];
  51. [resultAttributedString appendAttributedString:subAttrStr];
  52. //下次循环从当前匹配区域的下一个位置开始
  53. location = NSMaxRange(range);
  54. //找到要显示的区域内容加上
  55. NSRange rangeForDisplay = [result rangeAtIndex:groupIndexForDisplay];
  56. NSMutableAttributedString *displayStr = [[self attributedSubstringFromRange:rangeForDisplay]mutableCopy];
  57. //对其添加link属性
  58. NSString *linkValue = nil;
  59. if (groupIndexForValue==groupIndexForDisplay) {
  60. linkValue = displayStr.string;
  61. }else{
  62. NSRange rangeForValue = [result rangeAtIndex:groupIndexForValue];
  63. linkValue = [self attributedSubstringFromRange:rangeForValue].string;
  64. }
  65. [displayStr addAttribute:NSLinkAttributeName value:linkValue range:NSMakeRange(0, displayStr.length)];
  66. [resultAttributedString appendAttributedString:displayStr];
  67. }
  68. if (location < length) {
  69. //到这说明最后面还有非表情字符串
  70. NSRange range = NSMakeRange(location, length - location);
  71. NSAttributedString *subAttrStr = [self attributedSubstringFromRange:range];
  72. [resultAttributedString appendAttributedString:subAttrStr];
  73. }
  74. return resultAttributedString;
  75. }
  76. @end