富文本编辑器采坑,继承一下UITextView
UITextView
属性:typingAttributes
实时改变输入文字的样式
比如设置下划线:
- (void)setUnderLine:(BOOL)UnderLine{
_UnderLine = UnderLine;
self.attributes[NSUnderlineStyleAttributeName] = (_UnderLine?@1:@0);
self.typingAttributes = self.attributes;
}
改变光标位置:
self.selectedRange = NSMakeRange(rg.location+1, 0);
[self scrollRangeToVisible: self.selectedRange];
把html转为 NSAttributedString
的方法。
NSDictionary *options = @{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSFontAttributeName:[UIFont systemFontOfSize:15],
NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]
};
NSData *data = [contetn dataUsingEncoding:NSUnicodeStringEncoding];
NSAttributedString *att = [[NSAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil];
此处 contetn
为html字符串。
这里额外需要做的工作就是从html中提取image 。一般是链接,然后通过sdwebimage 请求,
从html 中过滤出 image 标签,
- (NSArray *)filterImageUrlFromHTML:(NSString *)html
{
if (!html) {
return @[];
}
NSMutableArray *resultArray = [NSMutableArray array];
static NSRegularExpression *regex = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSString *pattern = @"<(img|IMG)(.*?)(/>|></img>|>)";
regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionAllowCommentsAndWhitespace error:nil];
});
NSArray *result = [regex matchesInString:html options:NSMatchingReportCompletion range:NSMakeRange(0, html.length)];
for (NSTextCheckingResult *item in result) {
@autoreleasepool {
NSString *imgHtml = [html substringWithRange:[item rangeAtIndex:0]];
NSArray *tmpArray = nil;
if ([imgHtml rangeOfString:@"src=\""].location != NSNotFound) {
tmpArray = [imgHtml componentsSeparatedByString:@"src=\""];
} else if ([imgHtml rangeOfString:@"src="].location != NSNotFound) {
tmpArray = [imgHtml componentsSeparatedByString:@"src="];
}
if (tmpArray.count >= 2) {
NSString *src = tmpArray[1];
NSUInteger loc = [src rangeOfString:@"\""].location;
if (loc != NSNotFound) {
src = [src substringToIndex:src.length];
[resultArray addObject:src];
}
}
}
}
return resultArray;
}
接下来,通过enumerateAttributesInRange
遍历 NSAttributedString
找出图片,替换掉,就OK了。
通过 遍历NSAttributedString
生成html字符串的方法,遍历富文本,添加标签。方法如下:
- (NSString*)getHtmlEdit:(NSArray *)arr {
__block NSMutableString *htmlString = @"<p>".mutableCopy;
//枚举出所有的附件字符串-这个是顺序来的NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
[self enumerateAttributesInRange:NSMakeRange(0, self.length) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(NSDictionary *Attributes, NSRange range, BOOL *stop) {
//1. 通过range取出相应的字符串
NSString * title = [self.string substringWithRange:range];
CGNSTextAttachment * att = Attributes[@"NSAttachment"];
if (att) {
CGSize imgSize = att.image.size;
CGFloat newImgW = imgSize.width;
CGFloat newImgH = imgSize.height;
CGFloat textW = SCREEN_WIDTH - (30);
if (newImgW > textW) {
CGFloat ratio = textW / newImgW;
newImgW = textW;
newImgH *= ratio;
}
CGNSTextAttachment *attachment = [[CGNSTextAttachment alloc]initWithData:nil ofType:nil];
attachment.image = [UIImage imageNamed:@""];
attachment.bounds = CGRectMake(0, 0, newImgW, newImgH);
attachment.imageUrl = @"";
attachment.w = newImgW;
attachment.h = newImgH;
NSLog(@"imageUrl ==== %@", att.imageUrl);
}
if ([title containsString:@"\n"]) {
NSString* relpaceString = [title stringByReplacingOccurrencesOfString:@"\n" withString:@"<br>"];
[htmlString appendString:relpaceString];
}else if(att){
[htmlString appendString:@"</p>"];
[htmlString appendString:[NSString stringWithFormat:@"<img src=\"%@\" height=\"%.f\" width=\"%.f\">",att.imageUrl,att.h,att.w]];
[htmlString appendString:@"<p>"];
}else{
//1,是否加粗
NSString *bold = Attributes[@"NSStrokeWidth"];
UIFont * font= Attributes[@"NSFont"];
BOOL isBlold = NO;
if (font) {
NSString* name = font.fontDescriptor.postscriptName;
if (name.length && [name.lowercaseString containsString:@"bold"]) {
isBlold = YES;
}
}
if ([bold integerValue] <0.0 || isBlold) {
[htmlString appendString:@"<b>"];
}
//是否斜体
NSString *obliq = Attributes[@"NSObliqueness"];
if ([obliq floatValue] > 0.0) {
[htmlString appendString:@"<i>"];
}
//是否下划线
NSString *NSUnderline = Attributes[@"NSUnderline"];
if ([NSUnderline integerValue] > 0.0) {
[htmlString appendString:@"<u>"];
}
//是否删除线
NSString *NSdeleateline = Attributes[@"NSUnderlineStyleSingle"];
if ([NSdeleateline integerValue] > 0.0) {
[htmlString appendString:@"<s>"];
}
[htmlString appendString:@"<font "];
//2.颜色
UIColor * fontColor= Attributes[@"NSColor"];
if (fontColor) {
[htmlString appendString:[NSString stringWithFormat:@"color='%@'",[self HEXString:fontColor]]];
}
//3.字体
if (font) {
CGFloat size = font.fontDescriptor.pointSize;
[htmlString appendString:[NSString stringWithFormat:@" style='font-size:%.fpx;'",size]];
}
[htmlString appendString:@">"];
NSRange range = [title rangeOfString:@" "];
if (range.location != NSNotFound) {
NSUInteger leng = [title length];
NSString *temp = [NSString string];
for (int i=0; i<leng; i++) {
temp = [temp stringByAppendingString:@" "];
}
[htmlString appendString:temp];
}else{
// UIColor * bgColor= Attributes[@"NSBackgroundColor"];
// if (bgColor) {
// [htmlString appendString:[NSString stringWithFormat:@"<span style=\"background-color: %@;\">%@</span>",[self HEXString:bgColor],title]];
// }else{
[htmlString appendString:title];
// }
}
[htmlString appendString:@"</font>"];
if ([NSdeleateline integerValue] > 0.0) {
[htmlString appendString:@"</s>"];
}
if ([NSUnderline integerValue] > 0.0) {
[htmlString appendString:@"</u>"];
}
if ([obliq floatValue] > 0.0) {
[htmlString appendString:@"</i>"];
}
if ([bold integerValue] < 0.0 || isBlold) {
[htmlString appendString:@"</b>"];
}
}
}];
[htmlString appendString:@"</p>"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:@"<p></p>" withString:@""].mutableCopy;
NSLog(@"%@",htmlString);
return htmlString;
}