HBCoreLabel.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. //
  2. // HBCoreLabel
  3. // CoreTextMagazine
  4. //
  5. // Created by weqia on 13-10-27.
  6. // Copyright (c) 2013年 Marin Todorov. All rights reserved.
  7. //
  8. #import "HBCoreLabel.h"
  9. #import "NSStrUtil.h"
  10. #import "JXActionSheetVC.h"
  11. @interface HBCoreLabel () <JXActionSheetVCDelegate>
  12. @property (nonatomic, strong) JXActionSheetVC *actionVC;
  13. @end
  14. @implementation HBCoreLabel
  15. @synthesize match=_match,linesLimit;
  16. #pragma -mark 接口方法
  17. - (id)initWithFrame:(CGRect)frame
  18. {
  19. self = [super initWithFrame:frame];
  20. if (self) {
  21. // Initialization code
  22. }
  23. return self;
  24. }
  25. -(id)initWithCoder:(NSCoder *)aDecoder
  26. {
  27. self=[super initWithCoder:aDecoder];
  28. if(self){
  29. _copyEnableAlready=NO;
  30. }
  31. return self;
  32. }
  33. -(void)setAttributedText:(NSString *)attributedText
  34. {
  35. _attributed=YES;
  36. if([NSStrUtil isEmptyOrNull:attributedText ])
  37. {
  38. self.match=nil;
  39. return;
  40. }
  41. MatchParser * parser=[[MatchParser alloc]init];
  42. parser.width=self.bounds.size.width;
  43. [parser match:attributedText];
  44. self.match=parser;
  45. }
  46. -(void)setText:(NSString *)text
  47. {
  48. _attributed=NO;
  49. [super setText:text];
  50. }
  51. -(void)setMatch:(MatchParser *)match
  52. {
  53. if(match==_match)
  54. return;
  55. _attributed=YES;
  56. _match=match;
  57. [self setNeedsDisplay];
  58. }
  59. -(void)registerCopyAction
  60. {
  61. if(_copyEnableAlready)
  62. return;
  63. _copyEnableAlready=YES;
  64. self.userInteractionEnabled=YES;
  65. NSArray * gestures=self.gestureRecognizers;
  66. for(UIGestureRecognizer * gesture in gestures){
  67. if([gestures isKindOfClass:[UILongPressGestureRecognizer class]]){
  68. UILongPressGestureRecognizer * longPress=(UILongPressGestureRecognizer*)gestures;
  69. [longPress addTarget:self action:@selector(longPressAction:)];
  70. return;
  71. }
  72. }
  73. UILongPressGestureRecognizer * longPress=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
  74. [longPress setMinimumPressDuration:0.8];
  75. [self addGestureRecognizer:longPress];
  76. }
  77. - (void)drawRect:(CGRect)rect
  78. {
  79. // Drawing code
  80. if(!_attributed){
  81. [super drawRect:rect];
  82. return;
  83. }
  84. if(self.match!=nil&&[self.match isKindOfClass:[MatchParser class]]){
  85. CGContextRef context = UIGraphicsGetCurrentContext();
  86. // Flip the coordinate system
  87. CGContextSetTextMatrix(context, CGAffineTransformIdentity);
  88. CGContextSaveGState(context);
  89. CGContextTranslateCTM(context, 0, 10000);
  90. CGContextScaleCTM(context, 1.0, -1.0);
  91. if(self.match.numberOfLimitLines==0||(self.match.numberOfLimitLines>=self.match.numberOfTotalLines)||!self.linesLimit){
  92. CTFrameDraw((__bridge CTFrameRef)(self.match.ctFrame), context);
  93. for (NSDictionary* imageData in self.match.images) {
  94. NSString* img = [imageData objectForKey:MatchParserImage];
  95. UIImage * image=[UIImage imageNamed:img];
  96. NSValue * value=[imageData objectForKey:MatchParserRects];
  97. CGRect imgBounds;
  98. // if(![value isKindOfClass:[NSNull class]]){
  99. imgBounds=[[imageData objectForKey:MatchParserRects] CGRectValue];
  100. // }
  101. CGContextDrawImage(context, imgBounds, image.CGImage);
  102. }
  103. }
  104. else{
  105. NSArray *lines = (__bridge NSArray *)CTFrameGetLines((__bridge CTFrameRef)(self.match.ctFrame));
  106. CGPoint origins[[lines count]];
  107. CTFrameGetLineOrigins((__bridge CTFrameRef)(self.match.ctFrame), CFRangeMake(0, 0), origins); //2
  108. for(int lineIndex=0;lineIndex<self.match.numberOfLimitLines;lineIndex++){
  109. CTLineRef line=(__bridge CTLineRef)(lines[lineIndex]);
  110. CGContextSetTextPosition(context,origins[lineIndex].x,origins[lineIndex].y);
  111. // NSLog(@"%d: %f,%f",lineIndex,origins[lineIndex].x,origins[lineIndex].y);
  112. CTLineDraw(line, context);
  113. }
  114. for (NSDictionary* imageData in self.match.images) {
  115. NSString* img = [imageData objectForKey:MatchParserImage];
  116. UIImage * image=[UIImage imageNamed:img];
  117. NSValue * value=[imageData objectForKey:MatchParserRects];
  118. CGRect imgBounds;
  119. if(![value isKindOfClass:[NSNull class]])
  120. {
  121. imgBounds=[[imageData objectForKey:MatchParserRects] CGRectValue];
  122. NSNumber * number=[imageData objectForKey:MatchParserLine];
  123. int line=[number intValue];
  124. if(line<self.match.numberOfLimitLines){
  125. CGContextDrawImage(context, imgBounds, image.CGImage);
  126. }
  127. }
  128. }
  129. }
  130. }
  131. }
  132. #pragma -mark 事件响应方法
  133. -(void)longPressAction:(UIGestureRecognizer*)gesture
  134. {
  135. if (gesture.view!=self) {
  136. return;
  137. }
  138. if(gesture.state==UIGestureRecognizerStateBegan){
  139. self.backgroundColor=[UIColor lightGrayColor];
  140. self.actionVC = [[JXActionSheetVC alloc] initWithImages:@[] names:@[Localized(@"JX_Copy")]];
  141. self.actionVC.delegate = self;
  142. [g_App.window addSubview:self.actionVC.view];
  143. }else if(gesture.state==UIGestureRecognizerStateEnded){
  144. self.backgroundColor=[UIColor clearColor];
  145. }
  146. }
  147. -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
  148. {
  149. UITouch * touch1=[touches anyObject];
  150. CGPoint point=[touch1 locationInView:self];
  151. for(NSDictionary * dic in self.match.links){
  152. NSArray * rects=[dic objectForKey:MatchParserRects];
  153. for(NSValue * value in rects){
  154. CGRect rect= [value CGRectValue];
  155. if(point.x>rect.origin.x&&point.y>rect.origin.y&&point.x<(rect.origin.x+rect.size.width)&&point.y<(rect.origin.y+rect.size.height)){
  156. NSValue * rangeValue=[dic objectForKey:MatchParserRange];
  157. NSRange range1=[rangeValue rangeValue];
  158. id<MatchParserDelegate> data=self.match.data;
  159. _data=data;
  160. [data updateMatch:^(NSMutableAttributedString *string, NSRange range) {
  161. CTFontRef fontRef=CTFontCreateWithName((__bridge CFStringRef)(self.font.fontName),self.font.pointSize,NULL);
  162. if(range.location==range1.location){
  163. NSDictionary *attribute=[NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)fontRef,kCTFontAttributeName,(id)self.match.keyWorkColor.CGColor,kCTForegroundColorAttributeName,[NSNumber numberWithFloat:1],kCTStrokeWidthAttributeName,nil];
  164. [string addAttributes:attribute range:range];
  165. }else{
  166. NSDictionary *attribute=[NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)fontRef,kCTFontAttributeName,(id)self.match.keyWorkColor.CGColor,kCTForegroundColorAttributeName,nil];
  167. [string addAttributes:attribute range:range];
  168. }
  169. CFRelease(fontRef);
  170. }];
  171. NSArray * ges = [self.superview gestureRecognizers];
  172. for(UIGestureRecognizer * recognizer in ges){
  173. recognizer.enabled = NO;
  174. }
  175. ges=[self gestureRecognizers];
  176. for(UIGestureRecognizer * recognizer in ges){
  177. recognizer.enabled = NO;
  178. }
  179. _linkStr=[self.match.attrString.string substringWithRange:range1];
  180. _linkType=[dic objectForKey:MatchParserLinkType];
  181. [self setNeedsDisplay];
  182. touch=YES;
  183. return;
  184. }
  185. }
  186. }
  187. [super touchesBegan:touches withEvent:event];
  188. }
  189. -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
  190. {
  191. if (touch) {
  192. touch=NO;
  193. if(_data){
  194. [_data updateMatch:^(NSMutableAttributedString *string, NSRange range) {
  195. CTFontRef fontRef=CTFontCreateWithName((__bridge CFStringRef)(self.font.fontName),self.font.pointSize,NULL);
  196. NSDictionary *attribute=[NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)fontRef,kCTFontAttributeName,(id)self.match.keyWorkColor.CGColor,kCTForegroundColorAttributeName,nil];
  197. [string addAttributes:attribute range:range];
  198. }];
  199. NSArray * ges=[self.superview gestureRecognizers];
  200. for(UIGestureRecognizer * recognizer in ges){
  201. recognizer.enabled=YES;
  202. }
  203. ges=[self gestureRecognizers];
  204. for(UIGestureRecognizer * recognizer in ges){
  205. recognizer.enabled=YES;
  206. }
  207. [self setNeedsDisplay];
  208. if([_linkType isEqualToString:MatchParserLinkTypeUrl]){
  209. if(self.delegate&&[self.delegate respondsToSelector:@selector(coreLabel:linkClick:)]){
  210. [self.delegate coreLabel:self linkClick:_linkStr];
  211. }
  212. }else if ([_linkType isEqualToString:MatchParserLinkTypePhone]){
  213. if(self.delegate&&[self.delegate respondsToSelector:@selector(coreLabel:phoneClick:)]){
  214. [self.delegate coreLabel:self phoneClick:_linkStr];
  215. }
  216. }else if ([_linkType isEqualToString:MatchParserLinkTypeMobie]){
  217. if(self.delegate&&[self.delegate respondsToSelector:@selector(coreLabel:mobieClick:)]){
  218. [self.delegate coreLabel:self mobieClick:_linkStr];
  219. }
  220. }
  221. return;
  222. }
  223. }
  224. [super touchesCancelled:touches withEvent:event];
  225. }
  226. -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
  227. {
  228. if(touch){
  229. touch=NO;
  230. if(_data){
  231. [_data updateMatch:^(NSMutableAttributedString *string, NSRange range) {
  232. CTFontRef fontRef=CTFontCreateWithName((__bridge CFStringRef)(self.font.fontName),self.font.pointSize,NULL);
  233. NSDictionary *attribute=[NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)fontRef,kCTFontAttributeName,(id)self.match.keyWorkColor.CGColor,kCTForegroundColorAttributeName,nil];
  234. [string addAttributes:attribute range:range];
  235. CFRelease(fontRef);
  236. }];
  237. NSArray * ges=[self.superview gestureRecognizers];
  238. for(UIGestureRecognizer * recognizer in ges){
  239. recognizer.enabled=YES;
  240. }
  241. ges=[self gestureRecognizers];
  242. for(UIGestureRecognizer * recognizer in ges){
  243. recognizer.enabled=YES;
  244. }
  245. [self setNeedsDisplay];
  246. if([_linkType isEqualToString:MatchParserLinkTypeUrl]){
  247. if(self.delegate&&[self.delegate respondsToSelector:@selector(coreLabel:linkClick:)]){
  248. [self.delegate coreLabel:self linkClick:_linkStr];
  249. }
  250. }else if ([_linkType isEqualToString:MatchParserLinkTypePhone]){
  251. if(self.delegate&&[self.delegate respondsToSelector:@selector(coreLabel:phoneClick:)]){
  252. [self.delegate coreLabel:self phoneClick:_linkStr];
  253. }
  254. }else if ([_linkType isEqualToString:MatchParserLinkTypeMobie]){
  255. if(self.delegate&&[self.delegate respondsToSelector:@selector(coreLabel:phoneClick:)]){
  256. [self.delegate coreLabel:self phoneClick:_linkStr];
  257. }
  258. }
  259. return;
  260. }
  261. }
  262. [super touchesEnded:touches withEvent:event];
  263. }
  264. #pragma -mark 回调方法
  265. - (void)actionSheet:(JXActionSheetVC *)actionSheet didButtonWithIndex:(NSInteger)index {
  266. self.backgroundColor=[UIColor clearColor];
  267. if(index==0){
  268. if([self.match.source isKindOfClass:[NSString class]]){
  269. [UIPasteboard generalPasteboard].string=self.match.source;
  270. }
  271. }
  272. }
  273. @end