ifish/Ifish/UMCommunity/UMCommunitySDK/UMCommunityUI/CustomView/MutiStyleTextView/UMComMutiTextRun.m

379 lines
12 KiB
Objective-C

//
// UMComMutiTextRun.m
// UMCommunity
//
// Created by umeng on 15/8/19.
// Copyright (c) 2015年 Umeng. All rights reserved.
//
#import "UMComMutiTextRun.h"
#import <CoreText/CoreText.h>
#import "UMComResouceDefines.h"
//#import <UMComDataStorage/UMComUser.h>
//#import <UMComDataStorage/UMComComment.h>
//#import <UMComDataStorage/UMComLike.h>
//#import <UMComDataStorage/UMComTopic.h>
//#import "UMComSyntaxHighlightTextStorage.h"
NSString * const UMComMutiTextRunAttributedName = @"UMComMutiTextRunAttributedName";
@implementation UMComMutiTextRun
/**
* 向字符串中添加相关Run类型属性
*/
- (void)decorateToAttributedString:(NSMutableAttributedString *)attributedString range:(NSRange)range
{
if (attributedString.length == 0) {
return;
}
[attributedString addAttribute:UMComMutiTextRunAttributedName value:self range:range];
[attributedString addAttribute:(NSString *)kCTForegroundColorAttributeName value:self.textColor range:range];
[attributedString addAttribute:(NSString *)kCTFontAttributeName value:self.font range:range];
// self.font = [attributedString attribute:NSFontAttributeName atIndex:0 longestEffectiveRange:nil inRange:range];
}
/**
* 绘制Run内容
*/
- (void)drawRunWithRect:(CGRect)rect
{
}
- (instancetype)initWithText:(NSString *)text
font:(UIFont *)font
textColor:(UIColor *)color
range:(NSRange)range
{
self = [self init];
if (self) {
self.text = text;
if ([font isKindOfClass:[UIFont class]]) {
self.font = font;
}
if ([color isKindOfClass:[UIColor class]]) {
self.textColor = color;
}
self.range = range;
}
return self;
}
- (instancetype)init
{
self = [super init];
if (self) {
self.font = [UIFont systemFontOfSize:15];
self.textColor = [UIColor blueColor];
self.drawSelf = NO;
}
return self;
}
@end
@implementation UMComMutiTextRunClickUser
- (void)decorateToAttributedString:(NSMutableAttributedString *)attributedString range:(NSRange)range
{
[super decorateToAttributedString:attributedString range:range];
// [attributedString addAttribute:(NSString *)kCTForegroundColorAttributeName value:self.textColor range:range];
}
+ (NSArray *)runsWithAttributedString:(NSMutableAttributedString *)attributedString
font:(UIFont *)font
textColor:(UIColor *)color
checkWords:(NSArray *)checkWords
{
NSString *string = attributedString.string;
NSMutableArray *array = [NSMutableArray array];
for (NSString *userName in checkWords) {
NSString *userNameRegulaStr = UserRulerString;
NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:userNameRegulaStr options:NSRegularExpressionDotMatchesLineSeparators error:nil];
NSInteger matchCount = [regular numberOfMatchesInString:userName options:0 range:NSMakeRange(0, [userName length])];
if (matchCount > 0) {
NSRegularExpression *userNameRegular = [NSRegularExpression regularExpressionWithPattern:userName options:NSRegularExpressionDotMatchesLineSeparators error:nil];
NSArray *matchs = [userNameRegular matchesInString:string
options:0
range:NSMakeRange(0, [string length])];
for (NSTextCheckingResult *match in matchs) {
UMComMutiTextRunClickUser *run = [[UMComMutiTextRunClickUser alloc] initWithText:userName font:font textColor:color range:match.range];
[run decorateToAttributedString:attributedString range:match.range];
[array addObject:run];
}
}
}
return array;
}
@end
@implementation UMComMutiTextRunTopic
/**
* 向字符串中添加相关Run类型属性
*/
- (void)decorateToAttributedString:(NSMutableAttributedString *)attributedString range:(NSRange)range
{
if (attributedString.length == 0) {
return;
}
[super decorateToAttributedString:attributedString range:range];
}
+ (NSArray *)runsWithAttributedString:(NSMutableAttributedString *)attributedString
font:(UIFont *)font
textColor:(UIColor *)color
checkWords:(NSArray *)checkWords
{
NSString *string = attributedString.string;
NSMutableArray *array = [NSMutableArray array];
for (NSString *topicName in checkWords) {
NSString *topicNameRegulaStr = TopicRulerString;
NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:topicNameRegulaStr options:NSRegularExpressionDotMatchesLineSeparators error:nil];
NSInteger matchCount = [regular numberOfMatchesInString:topicName options:0 range:NSMakeRange(0, [topicName length])];
if (matchCount > 0) {
NSRegularExpression *topicNameRegular = [NSRegularExpression regularExpressionWithPattern:topicName options:NSRegularExpressionDotMatchesLineSeparators error:nil];
NSArray *matchs = [topicNameRegular matchesInString:string
options:0
range:NSMakeRange(0, [string length])];
for (NSTextCheckingResult *match in matchs) {
UMComMutiTextRunTopic *run = [[UMComMutiTextRunTopic alloc] initWithText:topicName font:font textColor:color range:match.range];
[run decorateToAttributedString:attributedString range:match.range];
[array addObject:run];
}
}
}
return array;
}
@end
@implementation UMComMutiTextRunURL
/**
* 向字符串中添加相关Run类型属性
*/
- (void)decorateToAttributedString:(NSMutableAttributedString *)attributedString range:(NSRange)range
{
if (attributedString.length == 0) {
return;
}
[super decorateToAttributedString:attributedString range:range];
// [attributedString addAttribute:(NSString *)kCTForegroundColorAttributeName value:self.textColor range:range];
}
+ (NSArray *)runsWithAttributedString:(NSMutableAttributedString *)attributedString
font:(UIFont *)font
textColor:(UIColor *)color
{
NSString *string = attributedString.string;
NSMutableArray *array = [NSMutableArray array];
NSError *error = nil;
NSString *regulaStr = @"((http[s]{0,1}|ftp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\,\\.\\-~!@#$%^&*+?:_/=<>]*)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\,\\.\\-~!@#$%^&*+?:_/=<>]*)?)";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regulaStr
options:NSRegularExpressionCaseInsensitive
error:&error];
if (error == nil)
{
NSArray *arrayOfAllMatches = [regex matchesInString:string
options:0
range:NSMakeRange(0, [string length])];
for (NSTextCheckingResult *match in arrayOfAllMatches)
{
NSString* substringForMatch = [string substringWithRange:match.range];
UMComMutiTextRunURL *run = [[UMComMutiTextRunURL alloc] initWithText:substringForMatch font:font textColor:color range:match.range];
[run decorateToAttributedString:attributedString range:match.range];
[array addObject:run ];
}
}
return array;
}
@end
@implementation UMComMutiTextRunDelegate
/**
* 向字符串中添加相关Run类型属性
*/
- (void)decorateToAttributedString:(NSMutableAttributedString *)attributedString range:(NSRange)range
{
[super decorateToAttributedString:attributedString range:range];
CTRunDelegateCallbacks callbacks;
callbacks.version = kCTRunDelegateVersion1;
callbacks.dealloc = UMComMutiTextRunDelegateDeallocCallback;
callbacks.getAscent = UMComMutiTextRunDelegateGetAscentCallback;
callbacks.getDescent = UMComMutiTextRunDelegateGetDescentCallback;
callbacks.getWidth = UMComMutiTextRunDelegateGetWidthCallback;
CTRunDelegateRef runDelegate = CTRunDelegateCreate(&callbacks, (__bridge void*)self);
[attributedString addAttribute:(NSString *)kCTRunDelegateAttributeName value:(__bridge id)runDelegate range:range];
CFRelease(runDelegate);
[attributedString addAttribute:(NSString *)kCTForegroundColorAttributeName value:(id)[UIColor clearColor].CGColor range:range];
}
#pragma mark - RunCallback
- (void)mutiTextRunDealloc
{
}
- (CGFloat)mutiTextRunGetAscent
{
return self.font.ascender;
}
- (CGFloat)mutiTextRunGetDescent
{
return self.font.descender;
}
- (CGFloat)mutiTextRunGetWidth
{
return self.font.ascender - self.font.descender;
}
#pragma mark - RunDelegateCallback
void UMComMutiTextRunDelegateDeallocCallback(void *refCon)
{
// UMComMutiTextRunDelegate *run =(__bridge UMComMutiTextRunDelegate *) refCon;
//
// [run mutiTextRunDealloc];
}
//--上行高度
CGFloat UMComMutiTextRunDelegateGetAscentCallback(void *refCon)
{
UMComMutiTextRunDelegate *run =(__bridge UMComMutiTextRunDelegate *) refCon;
return [run mutiTextRunGetAscent];
}
//--下行高度
CGFloat UMComMutiTextRunDelegateGetDescentCallback(void *refCon)
{
UMComMutiTextRunDelegate *run =(__bridge UMComMutiTextRunDelegate *) refCon;
return [run mutiTextRunGetDescent];
}
//-- 宽
CGFloat UMComMutiTextRunDelegateGetWidthCallback(void *refCon)
{
UMComMutiTextRunDelegate *run =(__bridge UMComMutiTextRunDelegate *) refCon;
return [run mutiTextRunGetWidth];
}
@end
@implementation UMComMutiTextRunEmoji
/**
* 返回表情数组
*/
+ (NSArray *) emojiStringArray
{
return [NSArray arrayWithObjects:@"[smile]",@"[cry]",@"[hei]",nil];
}
+ (NSArray *)runsForAttributedString:(NSMutableAttributedString *)attributedString
{
NSString *markL = @"[";
NSString *markR = @"]";
NSString *string = attributedString.string;
NSMutableArray *array = [NSMutableArray array];
NSMutableArray *stack = [NSMutableArray array];
for (int i = 0; i < string.length; i++)
{
NSString *s = [string substringWithRange:NSMakeRange(i, 1)];
if (([s isEqualToString:markL]) || ((stack.count > 0) && [stack[0] isEqualToString:markL]))
{
if (([s isEqualToString:markL]) && ((stack.count > 0) && [stack[0] isEqualToString:markL]))
{
[stack removeAllObjects];
}
[stack addObject:s];
if ([s isEqualToString:markR] || (i == string.length - 1))
{
NSMutableString *emojiStr = [[NSMutableString alloc] init];
for (NSString *c in stack)
{
[emojiStr appendString:c];
}
if ([[UMComMutiTextRunEmoji emojiStringArray] containsObject:emojiStr])
{
NSRange range = NSMakeRange(i + 1 - emojiStr.length, emojiStr.length);
[attributedString replaceCharactersInRange:range withString:@" "];
UMComMutiTextRunEmoji *run = [[UMComMutiTextRunEmoji alloc] init];
run.range = NSMakeRange(i + 1 - emojiStr.length, 1);
run.text = emojiStr;
run.drawSelf = YES;
[run decorateToAttributedString:attributedString range:run.range];
[array addObject:run];
}
[stack removeAllObjects];
}
}
}
return array;
}
/**
* 绘制Run内容
*/
- (void)drawRunWithRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
NSString *emojiString = [NSString stringWithFormat:@"%@.png",self.text];
UIImage *image = UMComImageWithImageName(emojiString);
if (image)
{
CGContextDrawImage(context, rect, image.CGImage);
}
}
@end