MMRichContentUtil.m 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. //
  2. // MMRichContentUtil.m
  3. // RichTextEditDemo
  4. //
  5. // Created by aron on 2017/7/24.
  6. // Copyright © 2017年 aron. All rights reserved.
  7. //
  8. #import "MMRichContentUtil.h"
  9. #import "MMRichImageModel.h"
  10. #import "MMRichTextModel.h"
  11. #import "MMRichTitleModel.h"
  12. #import "UIImage+Util.h"
  13. #import "UtilMacro.h"
  14. #import "MMTextView.h"
  15. #import "MMRichTextConfig.h"
  16. #define kRichContentEditCache @"RichContentEditCache"
  17. @implementation MMRichContentUtil
  18. + (NSString*)htmlContentFromRichContents:(NSArray*)richContents {
  19. NSMutableString *htmlContent = [NSMutableString string];
  20. for (int i = 0; i< richContents.count; i++) {
  21. NSObject* content = richContents[i];
  22. if ([content isKindOfClass:[MMRichImageModel class]]) {
  23. MMRichImageModel* imgContent = (MMRichImageModel*)content;
  24. [htmlContent appendString:[NSString stringWithFormat:@"<img src=\"%@\" width=\"%@\" height=\"%@\" />", imgContent.remoteImageUrlString, @(imgContent.image.size.width), @(imgContent.image.size.height)]];
  25. } else if ([content isKindOfClass:[MMRichTextModel class]]) {
  26. MMRichTextModel* textContent = (MMRichTextModel*)content;
  27. NSString* htmlText = [textContent.textContent stringByReplacingOccurrencesOfString:@"\n" withString:@"<br />"];
  28. [htmlContent appendString:@"<div>"];
  29. [htmlContent appendString:htmlText];
  30. [htmlContent appendString:@"</div>"];
  31. }
  32. }
  33. return htmlContent;
  34. }
  35. + (NSString*)plainContentFromRichContents:(NSArray*)richContents {
  36. NSMutableString *plainContent = [NSMutableString string];
  37. for (int i = 0; i< richContents.count; i++) {
  38. NSObject* content = richContents[i];
  39. if ([content isKindOfClass:[MMRichTextModel class]]) {
  40. MMRichTextModel* textContent = (MMRichTextModel*)content;
  41. [plainContent appendString:textContent.textContent];
  42. }
  43. }
  44. return plainContent;
  45. }
  46. // 验证Title不为空
  47. + (BOOL)validateTitle:(MMRichTitleModel*)titleModel {
  48. NSInteger textCount = [titleModel.textContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length;
  49. return textCount > 0;
  50. }
  51. // 验证内容,存在图片或者文字满足要求(1-20000)
  52. + (BOOL)validataContentNotEmptyWithRichContents:(NSArray*)richContents {
  53. NSInteger textCount = 0;
  54. for (int i = 0; i< richContents.count; i++) {
  55. NSObject* content = richContents[i];
  56. if ([content isKindOfClass:[MMRichImageModel class]]) {
  57. return YES;
  58. } else if ([content isKindOfClass:[MMRichTextModel class]]) {
  59. MMRichTextModel* textContent = (MMRichTextModel*)content;
  60. textCount += [textContent.textContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length;
  61. if (textCount > 0) {
  62. return YES;
  63. }
  64. }
  65. }
  66. return NO;
  67. }
  68. // 验证内容没有超过限制(1-20000)
  69. + (BOOL)validataContentNotOverflowWithRichContents:(NSArray*)richContents {
  70. NSInteger textCount = 0;
  71. for (int i = 0; i< richContents.count; i++) {
  72. NSObject* content = richContents[i];
  73. if ([content isKindOfClass:[MMRichTextModel class]]) {
  74. MMRichTextModel* textContent = (MMRichTextModel*)content;
  75. textCount += textContent.textContent.length;
  76. if (textCount > MMEditConfig.maxTextContentCount) {
  77. return NO;
  78. }
  79. }
  80. }
  81. return YES;
  82. }
  83. + (BOOL)validateImagesWithRichContents:(NSArray*)richContents {
  84. for (int i = 0; i< richContents.count; i++) {
  85. NSObject* content = richContents[i];
  86. if ([content isKindOfClass:[MMRichImageModel class]]) {
  87. MMRichImageModel* imgContent = (MMRichImageModel*)content;
  88. if (imgContent.isFailed == YES) {
  89. return NO;
  90. }
  91. }
  92. }
  93. return YES;
  94. }
  95. + (BOOL)validateImagesIsUploadIngWithRichContents:(NSArray*)richContents {
  96. for (int i = 0; i< richContents.count; i++) {
  97. NSObject* content = richContents[i];
  98. if ([content isKindOfClass:[MMRichImageModel class]]) {
  99. MMRichImageModel* imgContent = (MMRichImageModel*)content;
  100. if (imgContent.isDone == NO && imgContent.isFailed == NO) {
  101. return YES;
  102. }
  103. }
  104. }
  105. return NO;
  106. }
  107. + (NSArray*)imagesFromRichContents:(NSArray*)richContents {
  108. NSMutableArray* images = [NSMutableArray array];
  109. for (int i = 0; i< richContents.count; i++) {
  110. NSObject* content = richContents[i];
  111. if ([content isKindOfClass:[MMRichImageModel class]]) {
  112. MMRichImageModel* imgContent = (MMRichImageModel*)content;
  113. NSDictionary* imgDict
  114. = @{
  115. @"image" : ValueOrEmpty(imgContent.remoteImageUrlString),
  116. @"imageWidth" : @(imgContent.image.size.width),
  117. @"imageHeight" : @(imgContent.image.size.height),
  118. };
  119. [images addObject:imgDict];
  120. }
  121. }
  122. return images;
  123. }
  124. + (UIImage*)scaleImage:(UIImage*)originalImage {
  125. float scaledWidth = 800;
  126. return [originalImage scaletoSize:scaledWidth];
  127. }
  128. // 图片本地保存路径
  129. + (NSString*)imageSavedLocalPath {
  130. NSString *path=[self createDirectory:kRichContentEditCache];
  131. return path;
  132. }
  133. + (NSString*)saveImageToLocal:(UIImage*)image {
  134. NSString* path = [self.class imageSavedLocalPath];
  135. NSString* savedName = [self.class genRandomFileName];
  136. NSData* data = UIImageJPEGRepresentation(image, 1.0);
  137. NSString *fileSavedPath = [path stringByAppendingPathComponent:savedName];
  138. BOOL result = [data writeToFile:fileSavedPath atomically:YES];
  139. if (result) {
  140. return savedName;
  141. }
  142. return nil;
  143. }
  144. // 获取图片上传失败数
  145. + (NSInteger)imageUploadFailedCountFromRichContents:(NSArray*)richContents {
  146. NSInteger count = 0;
  147. for (int i = 0; i< richContents.count; i++) {
  148. NSObject* content = richContents[i];
  149. if ([content isKindOfClass:[MMRichImageModel class]]) {
  150. MMRichImageModel* imgContent = (MMRichImageModel*)content;
  151. if (imgContent.isFailed) count++ ;
  152. }
  153. }
  154. return count;
  155. }
  156. // 获取图片数
  157. + (NSInteger)imageCountFromRichContents:(NSArray*)richContents {
  158. NSInteger count = 0;
  159. for (int i = 0; i< richContents.count; i++) {
  160. NSObject* content = richContents[i];
  161. if ([content isKindOfClass:[MMRichImageModel class]]) {
  162. count++ ;
  163. }
  164. }
  165. return count;
  166. }
  167. // 计算TextView中的内容的高度
  168. + (float)computeHeightInTextVIewWithContent:(id)content {
  169. return [self computeHeightInTextVIewWithContent:content minHeight:0];
  170. }
  171. // 计算TextView中的内容的高度
  172. + (float)computeHeightInTextVIewWithContent:(id)content minHeight:(float)minHeight {
  173. UITextView* textView = nil;
  174. if ([content isKindOfClass:[NSString class]]) {
  175. textView = [self computePlainTextView];
  176. textView.text = (NSString*)content;
  177. } else if ([content isKindOfClass:[NSAttributedString class]]) {
  178. textView = [self computeAttrTextView];
  179. textView.attributedText = (NSAttributedString*)content;
  180. }
  181. CGRect frame = textView.frame;
  182. CGSize constraintSize = CGSizeMake(frame.size.width, MAXFLOAT);
  183. CGSize size = [textView sizeThatFits:constraintSize];
  184. textView.text = nil;
  185. textView.attributedText = nil;
  186. return MAX(size.height, minHeight);
  187. }
  188. // 是否需要显示placeholder
  189. + (BOOL)shouldShowPlaceHolderFromRichContents:(NSArray*)richContents {
  190. if (richContents.count == 1) {
  191. id content = richContents.firstObject;
  192. if ([content isKindOfClass:[MMRichTextModel class]]) {
  193. MMRichTextModel* textContent = (MMRichTextModel*)content;
  194. if (textContent.textContent.length <= 0 || [textContent.textContent isEqualToString:@"\n"]) {
  195. return YES;
  196. }
  197. }
  198. }
  199. return NO;
  200. }
  201. #pragma mark - ......::::::: helper :::::::......
  202. // 创建文件夹
  203. + (NSString *)createDirectory:(NSString *)path {
  204. BOOL isDir = NO;
  205. NSString *finalPath = [CACHE_PATH stringByAppendingPathComponent:path];
  206. if (!([[NSFileManager defaultManager] fileExistsAtPath:finalPath
  207. isDirectory:&isDir]
  208. && isDir))
  209. {
  210. [[NSFileManager defaultManager] createDirectoryAtPath:finalPath
  211. withIntermediateDirectories :YES
  212. attributes :nil
  213. error :nil];
  214. }
  215. return finalPath;
  216. }
  217. // 随机文件名
  218. + (NSString*)genRandomFileName {
  219. NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
  220. uint32_t random = arc4random_uniform(10000);
  221. return [NSString stringWithFormat:@"%@-%@.png", @(timeStamp), @(random)];
  222. }
  223. + (MMTextView *)computePlainTextView {
  224. static MMTextView* __mm_computePlainTextView;
  225. if (!__mm_computePlainTextView) {
  226. __mm_computePlainTextView = [[MMTextView alloc] init];
  227. __mm_computePlainTextView.font = MMEditConfig.defaultEditContentFont;
  228. __mm_computePlainTextView.textContainerInset = UIEdgeInsetsMake(MMEditConfig.editAreaTopPadding, MMEditConfig.editAreaLeftPadding, MMEditConfig.editAreaBottomPadding, MMEditConfig.editAreaRightPadding);
  229. __mm_computePlainTextView.scrollEnabled = NO;
  230. __mm_computePlainTextView.frame = CGRectMake(0, 0, kScreenWidth, 100000);
  231. }
  232. return __mm_computePlainTextView;
  233. }
  234. + (MMTextView *)computeAttrTextView {
  235. static MMTextView* __mm_computeAttrTextView;
  236. if (!__mm_computeAttrTextView) {
  237. __mm_computeAttrTextView = [[MMTextView alloc] init];
  238. __mm_computeAttrTextView.font = MMEditConfig.defaultEditContentFont;
  239. __mm_computeAttrTextView.textContainerInset = UIEdgeInsetsMake(MMEditConfig.editAreaTopPadding, MMEditConfig.editAreaLeftPadding, MMEditConfig.editAreaBottomPadding, MMEditConfig.editAreaRightPadding);
  240. __mm_computeAttrTextView.scrollEnabled = NO;
  241. __mm_computeAttrTextView.frame = CGRectMake(0, 0, kScreenWidth, 100000);
  242. }
  243. return __mm_computeAttrTextView;
  244. }
  245. @end