富文本編輯器採坑,繼承一下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;
}