// // NoteViewController.m // LMNoteDemo // // Created by littleMeaning on 2018/1/10. // Copyright © 2018年 littleMeaning. All rights reserved. // #import "LMNoteViewController.h" #import "LMNTextView.h" #import "LMNToolBar.h" #import "UIFont+LMNote.h" #import "LMNStore.h" #import "LMNDraft.h" #import "LMNImageView.h" #import "LMNImageInputViewController.h" #import "TestClass-Swift.h" #import #import "TFHpple.h" // 屏幕宽度 #define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width // 屏幕高度 #define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height #define NavHeight (KISIphoneX ? 88 : 64) #define KISIphoneX (CGSizeEqualToSize(CGSizeMake(375.f, 812.f), [UIScreen mainScreen].bounds.size) || CGSizeEqualToSize(CGSizeMake(812.f, 375.f), [UIScreen mainScreen].bounds.size)) #define BOUNSNavHeight CGRectMake(0, NavHeight, SCREEN_WIDTH, SCREEN_HEIGHT - NavHeight) #define BOUNS self.view.bounds @interface LMNoteViewController () @property (nonatomic, strong) LMNTextView *textView; @property (nonatomic, strong) LMNToolBar *toolBar; @property (nonatomic, strong) UIButton *editButton; @property (nonatomic, strong) LMNImageInputViewController *imageInputViewController; @property (nonatomic, weak) UIViewController *currentInputController; @property (nonatomic, assign) NSInteger cursorIndex; @property (nonatomic, assign) CGFloat keyboardHeight; @property (nonatomic, strong) NSMutableArray *imgIndexArr; @property (nonatomic, strong) NSMutableArray *imgUrlArr; @end @implementation LMNoteViewController - (instancetype)initWithDraft:(LMNDraft *)draft { self = [super init]; if (self) { _draft = draft; } return self; } - (void)loadSubviews { self.textView = ({ LMNTextView *textView = [[LMNTextView alloc] initWithTextStorage:self.draft.textStorage]; textView.backgroundColor = [UIColor whiteColor]; textView.spellCheckingType = UITextSpellCheckingTypeNo; textView.textColor = [UIColor colorWithRed:68/255.0 green:68/255.0 blue:68/255.0 alpha:1.0]; textView.delegate = self; textView.imgArr = [NSMutableArray arrayWithCapacity:10]; textView; }); [self.view addSubview:self.textView]; NSLog(@"old=\n%@",self.draft.textStorage); self.editButton = ({ UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setImage:[UIImage imageNamed:@"lmn_btn_edit"] forState:UIControlStateNormal]; button.backgroundColor = [UIColor colorWithWhite:.5f alpha:.75f]; button.clipsToBounds = YES; [button addTarget:self action:@selector(showToolBar:) forControlEvents:UIControlEventTouchUpInside]; button; }); [self.view addSubview:self.editButton]; self.toolBar = ({ LMNToolBar *toolBar = [LMNToolBar toolBar]; toolBar.delegate = self; toolBar.hidden = YES; toolBar; }); [self.view addSubview:self.toolBar]; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; [self loadSubviews]; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"保存" style:UIBarButtonItemStylePlain target:self action:@selector(export)]; [self.navigationItem.rightBarButtonItem setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont boldSystemFontOfSize:14],NSFontAttributeName, nil] forState:UIControlStateNormal]; self.navigationItem.title = @"编辑商品详情"; UIView *containerView = [UIView new]; containerView.frame = (CGRect){.size = CGSizeMake(34, 30)}; // 系统BarButtonItem大小(34, 30) UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom]; button1.frame = (CGRect){.size = CGSizeMake(34, 30)}; [button1 addTarget:self action:@selector(outVC) forControlEvents:UIControlEventTouchUpInside]; [containerView addSubview:button1]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(0, 5, 10, 17); [button setBackgroundImage:[UIImage imageNamed:@"fanhui"] forState:UIControlStateNormal]; [button addTarget:self action:@selector(outVC) forControlEvents:UIControlEventTouchUpInside]; [containerView addSubview:button]; self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:containerView]; // self.textView.text = @"ugh\nCccc\nThe new kJt"; // [self.textView updateExclusionPaths]; // [self.textView insertImage:[UIImage imageNamed:@"banner"] atIndex:4]; // [self.textView insertImage:[UIImage imageNamed:@"banner"] atIndex:9]; } - (void)setHtmlStr:(NSString *)htmlStr { _htmlStr = htmlStr; } - (void)outVC { NSLog(@"outvc====outvc"); [self.navigationController popViewControllerAnimated:YES]; // [self.textView insertImage:[UIImage imageNamed:@"lmn_tool_image"] atIndex:self.cursorIndex]; // self.textView.text = @"ugh\nCccc\nThe new kJt"; // [self.textView updateExclusionPaths]; // [self.textView insertImage:[UIImage imageNamed:@"banner"] atIndex:4]; // [self.textView insertImage:[UIImage imageNamed:@"banner"] atIndex:9]; } - (void)layoutTextView { CGFloat toolbarHeight = 44.f; self.textView.frame = BOUNS; self.toolBar.frame = ({ CGRect rect = BOUNS; rect.size.height = toolbarHeight; rect.origin.y = CGRectGetHeight(BOUNS) - CGRectGetHeight(rect) - self.keyboardHeight; rect; }); UIEdgeInsets insets = self.textView.contentInset; insets.bottom = self.keyboardHeight + 10.f; if (self.toolBar.hidden == NO) { insets.bottom += toolbarHeight; } self.textView.contentInset = insets; self.textView.textColor = [UIColor colorWithRed:68/255.0 green:68/255.0 blue:68/255.0 alpha:1.0]; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; [self layoutTextView]; self.editButton.frame = ({ CGRect rect = CGRectZero; rect.size = CGSizeMake(50.f, 50.f); rect.origin.x = CGRectGetWidth(BOUNS) - 50.f - 20.f; rect.origin.y = CGRectGetHeight(BOUNS) - 50.f - 20.f - self.keyboardHeight; rect; }); self.editButton.layer.cornerRadius = 25.f; self.toolBar.frame = ({ CGRect rect = BOUNS; rect.origin.y = CGRectGetHeight(rect) - 44.f - self.keyboardHeight; rect.size.height = 44.f; rect; }); //展示旧数据 if (_htmlStr.length > 0) { NSString *content = [self getStingByData:_htmlStr]; self.textView.text = content; [self.textView updateExclusionPaths]; for (int i = 0; i < self.imgIndexArr.count ; i++) { NSString *indexStr = self.imgIndexArr[i]; LMNImageView *imageView = [self.textView insertImage:[UIImage imageNamed:@"lmn_tool_image"] atIndex:indexStr.integerValue]; NSLog(@"图片index==%@",indexStr); NSString *url = self.imgUrlArr[i]; [self.textView.imgArr addObject:url]; imageView.imageUrl = url; } _htmlStr = @""; } // [self.textView insertImage:[UIImage imageNamed:@"banner"] atIndex:0]; // [self.textView insertImage:[UIImage imageNamed:@"banner"] atIndex:1]; // [self.textView insertImage:[UIImage imageNamed:@"banner"] atIndex:2]; // [self.textView insertImage:[UIImage imageNamed:@"banner"] atIndex:3]; // [self.textView insertImage:[UIImage imageNamed:@"banner"] atIndex:4]; // [self.textView insertImage:[UIImage imageNamed:@"banner"] atIndex:5]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.navigationController.navigationBar setHidden:NO]; [self addObservers]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self removeObservers]; [self saveDraft]; } - (void)addObservers { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; } - (void)removeObservers { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)saveDraft { __block NSString *firstLine = nil; NSCharacterSet *characterSet = [NSCharacterSet whitespaceCharacterSet]; [self.textView.text enumerateLinesUsingBlock:^(NSString * _Nonnull line, BOOL * _Nonnull stop) { line = [line stringByTrimmingCharactersInSet:characterSet]; if (line.length > 0) { firstLine = line; *stop = YES; } }]; if (firstLine.length > 0) { self.draft.name = firstLine; self.draft.textStorage = (LMNTextStorage *)self.textView.textStorage; NSLog(@"last=\n%@",self.textView.textStorage); [self.draft save]; } else { [self.draft delete]; } } - (void)export { [self.textView exportHTML:^(BOOL succeed, NSString *html) { NSLog(@"html:\n%@", [NSString stringWithFormat:@"%@",html]); if (self.delegatedata && [self.delegatedata respondsToSelector:@selector(getHTMLByVc:)]) { [self.delegatedata getHTMLByVc:html]; [self.navigationController popViewControllerAnimated:YES]; } }]; } - (NSString *)getStingByData:(NSString *)htmlString { // 将html字符串转为NSData NSString *content = @""; self.imgIndexArr = [NSMutableArray arrayWithCapacity:10]; self.imgUrlArr = [NSMutableArray arrayWithCapacity:10]; NSData *data = [htmlString dataUsingEncoding:NSUTF8StringEncoding]; // 创建Hpple对象 TFHpple * doc = [[TFHpple alloc] initWithHTMLData:data]; // 搜索XPath寻找标签 NSArray *elements = [doc searchWithXPathQuery:@"//p"]; for (TFHppleElement * element in elements) { NSLog(@"content:%@" , [element content]); if (content.length == 0) { content = [element content]; }else{ NSString *tempC = [element content]; if (tempC.length > 0) { content = [NSString stringWithFormat:@"%@\n%@",content,[element content]]; } } NSString *tempContent = [element content]; if (tempContent.length == 0 && self.imgIndexArr.count != 0) { content = [NSString stringWithFormat:@"%@\n",content]; } TFHppleElement *imgDic = [element firstChildWithTagName:@"img"]; if (imgDic) { NSString *src = [[imgDic attributes]objectForKey:@"src"]; NSLog(@"src:%@", src); if (content.length == 0) { if (self.imgIndexArr.count == 0) { [self.imgIndexArr addObject:@"0"]; }else{ NSString *index = [NSString stringWithFormat:@"%ld",(content.length + self.imgIndexArr.count)]; [self.imgIndexArr addObject:index]; } }else{ NSString *index = [NSString stringWithFormat:@"%ld",(content.length + self.imgIndexArr.count)]; [self.imgIndexArr addObject:index]; } NSString *imgSrc = @"https://c.gelifood.com/"; // NSString *imgSrc = @"https://cms.gelifood.com/"; NSString *imgurl = [src stringByReplacingOccurrencesOfString:imgSrc withString:@""]; [self.imgUrlArr addObject:imgurl]; } } return content; } #pragma mark - input - (LMNImageInputViewController *)imageInputViewController { if (!_imageInputViewController) { _imageInputViewController = [[LMNImageInputViewController alloc] init]; _imageInputViewController.delegate = self; } return _imageInputViewController; } - (void)changeTextInputForTag:(LMNToolBarItemTag)tag { UIViewController *inputViewController = nil; switch (tag) { case LMNToolBarItemTagImage: inputViewController = self.imageInputViewController; self.cursorIndex = NSMaxRange(self.textView.selectedRange); break; default: break; } if (inputViewController && self.currentInputController != inputViewController) { CGRect rect = BOUNS; rect.size.height = 400.f; rect.origin.y = CGRectGetHeight(BOUNS) - CGRectGetHeight(rect); inputViewController.view.frame = rect; } self.currentInputController = inputViewController; [self.textView resignFirstResponder]; } #pragma mark - private - (void)showToolBar:(UIButton *)button { self.editButton.hidden = YES; self.toolBar.hidden = NO; [self.textView becomeFirstResponder]; } - (void)reloadToolBar { NSMutableDictionary *attributes = [self.textView.typingAttributes mutableCopy]; LMNLineMode mode = [self.textView lineModeForRange:self.textView.selectedRange]; NSString *selectedStr = [self.textView.text substringWithRange:self.textView.selectedRange]; BOOL isMultiLine = [selectedStr containsString:@"\n"]; [self.toolBar reloadDataWithTypingAttributes:attributes mode:mode isMultiLine:isMultiLine]; } - (void)showInputView { CGRect rect = self.currentInputController.view.frame; [self.view addSubview:self.currentInputController.view]; self.currentInputController.view.frame = CGRectOffset(rect, 0, CGRectGetHeight(rect)); [UIView animateWithDuration:0.3 animations:^{ self.currentInputController.view.frame = rect; }]; } - (void)hideInputView { if (self.currentInputController) { [UIView animateWithDuration:0.3 animations:^{ CGRect rect = self.currentInputController.view.frame; self.currentInputController.view.frame = CGRectOffset(rect, 0, CGRectGetHeight(rect)); } completion:^(BOOL finished) { [self.currentInputController.view removeFromSuperview]; self.currentInputController = nil; }]; } [self.view setNeedsLayout]; } #pragma mark - Keyboard - (void)keyboardWillShow:(NSNotification *)notification { NSDictionary *info = [notification userInfo]; CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size; if (self.keyboardHeight == keyboardSize.height) { return; } self.keyboardHeight = keyboardSize.height; [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{ [self layoutTextView]; } completion:nil]; } - (void)keyboardWillHide:(NSNotification *)notification { if (self.keyboardHeight == 0) { return; } self.keyboardHeight = 0; [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{ [self layoutTextView]; } completion:nil]; } #pragma mark - - (void)textViewDidBeginEditing:(UITextView *)textView { self.editButton.hidden = YES; self.toolBar.hidden = NO; [self hideInputView]; } - (void)textViewDidEndEditing:(UITextView *)textView { self.toolBar.hidden = YES; if (self.currentInputController) { [self showInputView]; } else { self.editButton.hidden = NO; } [self.view setNeedsLayout]; } - (void)textViewDidChangeSelection:(UITextView *)textView { [self reloadToolBar]; } #pragma mark - - (void)lmn_toolBar:(LMNToolBar *)toolBar didChangedMode:(LMNLineMode)mode { [self.textView setLineMode:mode forRange:self.textView.selectedRange]; [self reloadToolBar]; } - (void)lmn_toolBar:(LMNToolBar *)toolBar didChangedAttributes:(NSDictionary *)attributes { BOOL bold = [attributes[LMFontBoldAttributeName] boolValue]; BOOL italic = [attributes[LMFontItalicAttributeName] boolValue]; BOOL underline = [attributes[LMFontUnderlineAttributeName] boolValue]; BOOL strikethrough = [attributes[LMFontStrikethroughAttributeName] boolValue]; NSMutableDictionary *typingAttributes = [self.textView.typingAttributes mutableCopy]; UIFont *font = typingAttributes[NSFontAttributeName]; typingAttributes[NSFontAttributeName] = [UIFont fontWithFontSize:font.fontSize bold:bold italic:italic]; if (underline) { typingAttributes[NSUnderlineStyleAttributeName] = @(NSUnderlineStyleSingle); } else { [typingAttributes removeObjectForKey:NSUnderlineStyleAttributeName]; } if (strikethrough) { typingAttributes[NSStrikethroughStyleAttributeName] = @(1); } else { [typingAttributes removeObjectForKey:NSStrikethroughStyleAttributeName]; } self.textView.typingAttributes = typingAttributes; [self.textView setAttributesForSelection:typingAttributes]; } - (void)lmn_toolBar:(LMNToolBar *)toolBar didChangedTextAlignment:(NSTextAlignment)alignment { [self.textView setTextAlignmentForSelection:alignment]; } - (void)lmn_toolBar:(LMNToolBar *)toolBar didSelectedItemWithTag:(LMNToolBarItemTag)tag { [self changeTextInputForTag:tag]; } - (void)lmn_toolBarClose:(LMNToolBar *)toolBar { self.editButton.hidden = NO; self.toolBar.hidden = YES; [self.textView resignFirstResponder]; } #pragma mark - #pragma mark -- 插入图片 - (void)lmn_imageInput:(LMNImageInputViewController *)viewController didSelectPHAsset:(PHAsset *)asset { [self hideInputView]; self.editButton.hidden = NO; CGFloat imageWidth = CGRectGetWidth([UIScreen mainScreen].bounds) - 40.f; CGSize targetSize = CGSizeMake(imageWidth, imageWidth); PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; options.synchronous = YES; options.networkAccessAllowed = YES; __block LMNImageView *imageView = nil; [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:targetSize contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage *result, NSDictionary *info) { //请求上传图片 TestClass *model = [[TestClass alloc]init]; NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:10]; [dict setValue:@"RQdwz5QKpeg=" forKey:@"user_token"]; [model saveFileWithImage:result params:dict success:^(NSDictionary * data) { if ([[NSString stringWithFormat:@"%@",data[@"code"]]isEqualToString:@"1"]) { if (!imageView) { // imageView = [self.textView insertImage:result atIndex:self.cursorIndex]; imageView = [self.textView insertImage:[UIImage imageNamed:@"lmn_tool_image"] atIndex:self.cursorIndex]; NSLog(@"原图片indexd===%ld",self.cursorIndex); } else { imageView.image = result; } NSDictionary *dataDic = data[@"data"]; NSString *url = dataDic[@"url"]; [self.textView.imgArr addObject:url]; imageView.imageUrl = url; } } failture:^(NSError * error) { }]; }]; } - (void)lmn_imageInputClose:(LMNImageInputViewController *)viewController { [self hideInputView]; self.editButton.hidden = NO; } @end