iOS 富文本編輯器-WKWebView

iOS 13 以後再也不支持 UIWebView,因此將以前一篇文章iOS 富文本編輯器-UIWebView中 UIWebView 替換爲 WKWebView。如下爲更換到 WKWebView 的一些知識點。html

富文本編輯器設計的知識點

Objective-C 語言調用 JavaScript 語言

經過WKWebView的 - (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;的方法來實現的。這樣咱們就能夠實現文字的加粗、下劃線、斜體等等一切咱們想要的樣式。java

詳見個人項目中 WKWebView+VJJSTool 文件。git

JavaScript 語言調用 Objective-C 語言

第一步:咱們須要在WKWebView建立的過程當中初始化添加ScriptMessageHandlergithub

WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
        WKUserContentController *userController = [[WKUserContentController alloc] init];
        configuration.userContentController = userController;
        _mainWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, KMainWidth, KMainHeight) configuration:configuration];
        [userController addScriptMessageHandler:self name:@"currentCookies"];
複製代碼

而後實現代理方法.監聽JS的回調.web

//JS調用的OC回調方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
    
    if ([message.name isEqualToString:@"jsMethod"]) {
        //
    }
}
複製代碼

而後在Html文件中添加點擊方法.bash

<div id="button_div" onclick="buttonDivAction()">
      點擊調用OC方法
</div>
複製代碼

緊接着.在js文件中實現點擊事件.這時候要注意的是ScriptMessageHandler的名稱要與上面定義的一致.編輯器

function buttonDivAction() {
    window.webkit.messageHandlers. jsMethod.postMessage({
        "body": "buttonActionMessage"
    });
}
複製代碼

輸入文字時,插入符號位置計算

ZSSRichTextEditor.jside

zss_editor.updateOffset = function() {}

zss_editor.calculateEditorHeightWithCaretPosition = function() {}

複製代碼

新增標題與副標題

editor.html工具

<div id="vj_title">
     <input id="vj_article_title" maxlength="70" type="text" placeholder="請輸入標題">
</div>
<div id="vj_abstract-title">
    <input id="vj_article_abstract" maxlength="35" type="text" placeholder="請輸入文章摘要">
</div>
複製代碼

去掉鍵盤自帶的工具條

WKWebView+HackishAccessoryHiding.mpost

- (void)removeInputAccessoryViewFromWKWebView:(WKWebView *)webView {
    UIView *targetView;

    for (UIView *view in webView.scrollView.subviews) {
        if([[view.class description] hasPrefix:@"WKContent"]) {
            targetView = view;
        }
    }

    if (!targetView) {
        return;
    }

    NSString *noInputAccessoryViewClassName = [NSString stringWithFormat:@"%@_NoInputAccessoryView", targetView.class.superclass];
    Class newClass = NSClassFromString(noInputAccessoryViewClassName);

    if(newClass == nil) {
        newClass = objc_allocateClassPair(targetView.class, [noInputAccessoryViewClassName cStringUsingEncoding:NSASCIIStringEncoding], 0);
        if(!newClass) {
            return;
        }

        Method method = class_getInstanceMethod([self class], @selector(inputAccessoryView));

        class_addMethod(newClass, @selector(inputAccessoryView), method_getImplementation(method), method_getTypeEncoding(method));

        objc_registerClassPair(newClass);
    }

    object_setClass(targetView, newClass);
}

- (id)inputAccessoryView {
    return nil;
}
複製代碼

自動彈出鍵盤

實現和 UIWebView 中 keyboardDisplayRequiresUserAction 相同功能。即在 web 頁面 focus 得到焦點狀態下彈出鍵盤,UIWebView 中 keyboardDisplayRequiresUserAction 設置爲 NO 就能夠實現,可是WKWebView 中沒有此屬性,能夠經過如下方式實現:

WKWebView+HackishAccessoryHiding.m

-(void)allowDisplayingKeyboardWithoutUserAction {
    Class class = NSClassFromString(@"WKContentView");
        NSOperatingSystemVersion iOS_11_3_0 = (NSOperatingSystemVersion){11, 3, 0};
        NSOperatingSystemVersion iOS_12_2_0 = (NSOperatingSystemVersion){12, 2, 0};
        NSOperatingSystemVersion iOS_13_0_0 = (NSOperatingSystemVersion){13, 0, 0};
        char * methodSignature = "_startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:";

        if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_13_0_0]) {
            methodSignature = "_elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:";
        } else if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_12_2_0]) {
            methodSignature = "_elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:";
        }

        if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_11_3_0]) {
            SEL selector = sel_getUid(methodSignature);
            Method method = class_getInstanceMethod(class, selector);
            IMP original = method_getImplementation(method);
            IMP override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, BOOL arg3, id arg4) {
                ((void (*)(id, SEL, void*, BOOL, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3, arg4);
            });
            method_setImplementation(method, override);
        } else {
            SEL selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:");
            Method method = class_getInstanceMethod(class, selector);
            IMP original = method_getImplementation(method);
            IMP override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, id arg3) {
                ((void (*)(id, SEL, void*, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3);
            });
            method_setImplementation(method, override);
        }

}
複製代碼

詳細代碼請看項目 github.com/Vergil-wj/R…

參考資料:

ZSSRichTextEditor

WGEditor

淺談WKWebView使用、JS的交互

相關文章
相關標籤/搜索