0
点赞
收藏
分享

微信扫一扫

iOS小技能:富文本编辑器(下篇)

引言

  1. 富文本编辑器的应用场景: 编辑商品详情
  1. 设计思路: 编辑器基于WKWebview实现,Editor使用WKWebview加载一个本地editor.html文件,Editor使用​​eval(html代码)传输给服务器。

"remark":"<p>商品详情看看</p>\n<p style=\"text-align: right;\">jjjj<img src=\"http://bug.xxx.com:7000/zentao/file-read-6605.png\" alt=\"dddd\" width=\"750\" height=\"4052\" /></p>\n<p style=\"text-align: right;\"> </p>\n<p style=\"text-align: right;\"> </p>\n<p style=\"text-align: right;\"> </p>\n<p style=\"text-align: right;\"> </p>\n<p style=\"text-align: right;\"> </p>\n<p style=\"text-align: right;\"> </p>\n<p style=\"text-align: right;\"><img src=\"http://bug.xxx.com:7000/zentao/file-read-6605.png\" alt=\"\" width=\"750\" height=\"4052\" /></p>"

  1. 使用IQKeyboardManager 键盘管理工具,布局采用Masonry,MVVM数据绑定。
  2. 界面设计:推荐把工具栏添加到键盘,或者放在富文本编辑器的顶部


I 上篇: 核心代码逻辑

II 工具栏设计(含demo)

2.1 工具栏在富文本编辑器的底部

iOS小技能:富文本编辑器(下篇)_插入图片_02


2.2 工具栏在富文本编辑器的顶部

iOS小技能:富文本编辑器(下篇)_webview_03

-(WKWebView *)editorView{
if (!_editorView) {

WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc]init];
WKUserContentController *userCon = [[WKUserContentController alloc]init];
config.userContentController = userCon;

WKWebView *tmp = [[WKWebView alloc]initWithFrame:CGRectZero configuration:config];

//223
// [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, pDeviceWidth, self.view.frame.size.height-KWEditorBar_Height) configuration:config];


_editorView = tmp;


// [userCon addScriptMessageHandler:self name:@"column"];
tmp.navigationDelegate = self;


tmp.hidesInputAccessoryView = YES;// 去掉键盘自带的工具条


tmp.scrollView.bounces = NO;
tmp.backgroundColor = [UIColor whiteColor];

// anObserver:观察者对象,这个对象必须实现observeValueForKeyPath:ofObject:change:context:方法,以响应属性的修改通知。
// keyPath:被监听的属性。这个值不能为nil。
// options:监听选项,这个值可以是NSKeyValueObservingOptions选项的组合。关于监听选项,我们会在下面介绍。
// context:任意的额外数据,我们可以将这些数据作为上下文数据,它会传递给观察者对象的observeValueForKeyPath:ofObject:change:context:方法。这个参数的意义在于用于区分同一对象监听同一属性(从属于同一对象)的多个不同的监听。我们将在下面看到。
//
[tmp addObserver:self forKeyPath:@"URL" options:NSKeyValueObservingOptionNew context:nil];


[self addSubview:tmp];

__weak __typeof__(self) weakSelf = self;

[tmp mas_makeConstraints:^(MASConstraintMaker *make) {

make.bottom.offset(0);//test


make.height.mas_equalTo(kAdjustRatio(223));

// make.top.offset(0);
make.left.right.offset(0);
make.top.equalTo(weakSelf.toolBarView.mas_bottom).offset(0);


}];

[self initConfig];

}
return _editorView;
}

- (KNEditorBar *)toolBarView{
if (!_toolBarView) {


KNEditorBar *tmp = [KNEditorBar editorBar];

_toolBarView = tmp;


tmp.frame = CGRectMake(0,self.frame.size.height - KWEditorBar_Height, self.frame.size.width, KWEditorBar_Height);



tmp.backgroundColor = rgb(237, 237, 237);

[self addSubview:tmp];
__weak __typeof__(self) weakSelf = self;

[tmp mas_makeConstraints:^(MASConstraintMaker *make) {

make.left.right.offset(0);

make.height.mas_equalTo(KWEditorBar_Height);
// make.top.equalTo(weakSelf.editorView.mas_bottom).offset(0);
make.top.offset(KWFontBar_Height-13);


// make.bottom.offset(0);

}];

tmp.delegate = self;

[tmp addObserver:self forKeyPath:@"transform" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];


self.editorView.associatedObject = tmp;

}
return _toolBarView;
}


- (KNFontStyleBar *)fontBar{
if (!_fontBar) {
_fontBar = [[KNFontStyleBar alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.toolBarView.frame) - KWFontBar_Height - KWEditorBar_Height, self.frame.size.width, KWFontBar_Height)];



_fontBar.delegate = self;

[_fontBar.heading2Item setSelected:YES];

}
return _fontBar;
}




#pragma
- (void)editorBar:(KNEditorBar *)editorBar didClickIndex:(k_RichToolBarButtonIndex)buttonIndex{


switch (buttonIndex) {
case k_RichToolBarButtonIndex4KeyboardButton:{//键盘唤醒与隐藏

NSLog(@"%f",self.toolBarView.transform.ty);


// if (self.toolBarView.transform.ty < 0) {

if (self.models.isVisable) {



[self.editorView hiddenKeyboard];

// self.toolBarView.keyboardButton.selected = NO;


}else{

[self.editorView focusTextEditor];

self.toolBarView.keyboardButton.selected = YES;

}
}
break;
case k_RichToolBarButtonIndex4undoButton:{//后退
[self.editorView undo];
}
break;
case k_RichToolBarButtonIndex4redoButton:{//前进
[self.editorView redo];
}
break;
case k_RichToolBarButtonIndex4fontButton:{//字体
editorBar.fontButton.selected = !editorBar.fontButton.selected;

if (editorBar.fontButton.selected) {

[self addSubview:self.fontBar];

__weak __typeof__(self) weakSelf = self;

[self.fontBar mas_updateConstraints:^(MASConstraintMaker *make) {

// _fontBar = [[KNFontStyleBar alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.toolBarView.frame) - KWFontBar_Height - KWEditorBar_Height, self.frame.size.width, KWFontBar_Height)];

make.bottom.equalTo(weakSelf.toolBarView.mas_top);


make.left.right.offset(0);

// make.width.offset(0);

make.height.mas_equalTo( KWFontBar_Height);



}];

}else{


[self.fontBar removeFromSuperview];




}

}
break;
case k_RichToolBarButtonIndex4linkButton:{//超连接
[self insertLink];
}
break;
case k_RichToolBarButtonIndex4imageButton:{//图片

[self insertImage];
}
break;
default:
break;
}

}

III 常见问题

3.1 隐藏键盘失去焦点时,图片内容被清空

问题: 标签的占位符,通过监听失去焦点事件,如果文本trim之后长度为0,就清空div数据,显示占位符。

原因:​​element.text()​​ 获取的是文本,只判断了文本,而忽略了img标签。

<div id="zss_editor_content" class="zs_editor_content" contenteditable="true" placeholder="请输入文章正文"></div>

zss_editor.setPlaceholder = function(placeholder) {

var editor = $('#zss_editor_content');

//set placeHolder
editor.attr("placeholder",placeholder);

//set focus
editor.focusout(function(){//当元素失去焦点时触发 focusout 事件
var element = $(this);
if

解决方式: 修改占位符的判断条件

//element.text() 获取的是文本,只判断了文本,而忽略了img标签。,所以换成html()判断子标签
// window.alert(element.html());


if (!element.html().trim().length ) {
element.empty();
}

iOS小技能:富文本编辑器(下篇)_插入图片_04

去除换行和空格在判断是否内容为空

if (!html.length || html=="<br>") {

element.empty();
}

3.2 插入图片无效

问题:插入图片无效 原因: 点击插入图片按钮时,WebView获取到焦点 解决方式:点击插入图片按钮时,尝试获取焦点。

#pragma
//https://csdnimg.cn/medal/blinknewcomer@240.png
-(void)insertImage{

if (!self.models.isVisable) {
[self.editorView focusTextEditor];// 获取焦点
}

[self.editorView prepareInsertImage];

if(self.models.insertImageBlock){
self.models.insertImageBlock(nil);
}



}
#pragma
- (void)insertLink {

if (!self.models.isVisable) {
[self.editorView focusTextEditor];// 获取焦点
}

[self.editorView prepareInsertImage];

if(self.models.showInsertLinkDialogBlockWithLink){

self.models.showInsertLinkDialogBlockWithLink(nil,nil);
}

// [self showInsertLinkDialogWithLink:nil title:nil];

3.3 插入的网络图片 只能添加到最后位置

问题:插入的网络图片 只能添加到最后位置,不能再中间插入。

原因: 插入图片时多次获取焦点,把焦点定位到最后的位置 解决:使用5.2 章节的方式

if (!self.viewModel.model4editor.isVisable) {

// [self.viewModel.model4editor.editorView focusTextEditor];

see also

公众号:iOS逆向

举报

相关推荐

0 条评论