From 0d7aa5c5b5453de200661d6a5d076fad4a82acf9 Mon Sep 17 00:00:00 2001 From: Engin Date: Thu, 12 Aug 2021 17:13:42 +0300 Subject: [PATCH 01/11] added setCode method --- RichEditorView/Assets/editor/rich_editor.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/RichEditorView/Assets/editor/rich_editor.js b/RichEditorView/Assets/editor/rich_editor.js index 6fc55d4e..b6f9035c 100644 --- a/RichEditorView/Assets/editor/rich_editor.js +++ b/RichEditorView/Assets/editor/rich_editor.js @@ -153,6 +153,14 @@ RE.redo = function() { document.execCommand('redo', false, null); }; +RE.setCode = function() { + if(window.getSelection().toString() != "") { + var code = window.getSelection().toString().replace(//ig, '>'); + var html ='
'+code+'

' + } + RE.insertHTML(html); +} + RE.setBold = function() { document.execCommand('bold', false, null); }; From be95a3947cd73c1246e00fb4a9163fe9b093f115 Mon Sep 17 00:00:00 2001 From: Engin Date: Thu, 12 Aug 2021 17:32:57 +0300 Subject: [PATCH 02/11] added code feature --- RichEditorView.xcodeproj/project.pbxproj | 5 +++++ RichEditorView/Assets/icons/code.png | Bin 0 -> 155 bytes RichEditorView/Classes/RichEditorOptionItem.swift | 6 +++++- RichEditorView/Classes/RichEditorView.swift | 4 ++++ 4 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 RichEditorView/Assets/icons/code.png diff --git a/RichEditorView.xcodeproj/project.pbxproj b/RichEditorView.xcodeproj/project.pbxproj index c421cf52..96ea45fe 100644 --- a/RichEditorView.xcodeproj/project.pbxproj +++ b/RichEditorView.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 284EE05E26C56851003E3F96 /* code.png in Resources */ = {isa = PBXBuildFile; fileRef = 284EE05D26C56851003E3F96 /* code.png */; }; 39FC98FB1DC788A1008FE5DD /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39FC98F91DC788A1008FE5DD /* String+Extensions.swift */; }; 39FC98FC1DC788A1008FE5DD /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39FC98FA1DC788A1008FE5DD /* UIColor+Extensions.swift */; }; 947A71A11C0F9DED00BDF9FC /* UIView+Responder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 947A71A01C0F9DED00BDF9FC /* UIView+Responder.swift */; }; @@ -84,6 +85,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 284EE05D26C56851003E3F96 /* code.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = code.png; sourceTree = ""; }; 39FC98F91DC788A1008FE5DD /* String+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "String+Extensions.swift"; path = "Classes/String+Extensions.swift"; sourceTree = ""; }; 39FC98FA1DC788A1008FE5DD /* UIColor+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIColor+Extensions.swift"; path = "Classes/UIColor+Extensions.swift"; sourceTree = ""; }; 947A71A01C0F9DED00BDF9FC /* UIView+Responder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+Responder.swift"; path = "Classes/UIView+Responder.swift"; sourceTree = ""; }; @@ -275,6 +277,7 @@ FBA6AB1F1AD3ED2D00721644 /* bg_color@2x.png */, FBA6AB201AD3ED2D00721644 /* bold.png */, FBA6AB211AD3ED2D00721644 /* bold@2x.png */, + 284EE05D26C56851003E3F96 /* code.png */, FBA6AB221AD3ED2D00721644 /* clear.png */, FBA6AB231AD3ED2D00721644 /* clear@2x.png */, FBA6AB241AD3ED2D00721644 /* h1.png */, @@ -400,6 +403,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = FBA6AAEF1AD3EC9F00721644; @@ -437,6 +441,7 @@ FBA6AB561AD3ED2D00721644 /* bold@2x.png in Resources */, FBA6AB6E1AD3ED2D00721644 /* justify_center@2x.png in Resources */, FBA6AB5A1AD3ED2D00721644 /* h1@2x.png in Resources */, + 284EE05E26C56851003E3F96 /* code.png in Resources */, FBA6AB721AD3ED2D00721644 /* justify_right@2x.png in Resources */, FBA6AB7D1AD3ED2D00721644 /* text_color.png in Resources */, FBA6AB621AD3ED2D00721644 /* h5@2x.png in Resources */, diff --git a/RichEditorView/Assets/icons/code.png b/RichEditorView/Assets/icons/code.png new file mode 100644 index 0000000000000000000000000000000000000000..beae38125f8d8e1acb61cfa5ec6c8730970087d0 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+iBu^K|5R21qFK*;Lpdi3 Date: Sun, 15 Aug 2021 23:52:56 +0300 Subject: [PATCH 03/11] font option --- .../Classes/RichEditorOptionItem.swift | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/RichEditorView/Classes/RichEditorOptionItem.swift b/RichEditorView/Classes/RichEditorOptionItem.swift index c6ed820d..2f13d0ed 100644 --- a/RichEditorView/Classes/RichEditorOptionItem.swift +++ b/RichEditorView/Classes/RichEditorOptionItem.swift @@ -50,6 +50,63 @@ public struct RichEditorOptionItem: RichEditorOption { } } + +public enum RichEditorTextSizeOption: RichEditorOption { + + public var image: UIImage? { + return nil + } + + public var title: String { + return "" + } + + public func action(_ editor: RichEditorToolbar) { + + } + + +} + + +public enum RichEditorFontOption: RichEditorOption { + + case Ariel + case CourierNew + case Georgia + case Impact + case LucidaConsole + case Tahoma + case TimesNewRoman + case Verdana + + public static let all: [RichEditorFontOption] = [ + .Ariel, .CourierNew, .Georgia, .Impact, .LucidaConsole, .Tahoma, .TimesNewRoman, .Verdana, + ] + + public var image: UIImage? { + return nil + } + + public var title: String { + switch self { + case .Ariel: return "Ariel" + case .CourierNew: return "Courier New" + case .Georgia: return "Georgia" + case .Impact: return "Impact" + case .LucidaConsole: return "Lucida Console" + case .Tahoma: return "Tahoma" + case .TimesNewRoman: return "Times New Roman" + case .Verdana: return "Verdana" + } + } + + public func action(_ toolbar: RichEditorToolbar) { + toolbar.editor?.setFont(self) + } + +} + /// RichEditorOptions is an enum of standard editor actions public enum RichEditorDefaultOption: RichEditorOption { From 50576f1038baedeac0373aac30b36255b8e54fae Mon Sep 17 00:00:00 2001 From: Engin KUK Date: Sun, 15 Aug 2021 23:53:58 +0300 Subject: [PATCH 04/11] font option added --- .../Classes/RichEditorToolbar.swift | 38 +++++++++++++++++++ RichEditorView/Classes/RichEditorView.swift | 16 +++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/RichEditorView/Classes/RichEditorToolbar.swift b/RichEditorView/Classes/RichEditorToolbar.swift index e7f543fd..e2b64d75 100644 --- a/RichEditorView/Classes/RichEditorToolbar.swift +++ b/RichEditorView/Classes/RichEditorToolbar.swift @@ -73,6 +73,44 @@ import UIKit private var toolbar: UIToolbar private var backgroundToolbar: UIToolbar + lazy var fontToolbar: UIToolbar = { + let bar = UIToolbar(frame: CGRect(x: 0, y:0, width: 800, height: 44)) + bar.isHidden = true + bar.autoresizingMask = .flexibleWidth + bar.alpha = 0 + + var buttons = [UIBarButtonItem]() + let options = RichEditorFontOption.all + for option in options { + let handler = { [weak self] in + if let strongSelf = self { + option.action(strongSelf) + } + } + let title = option.title + let button = RichBarButtonItem(title: title, handler: handler) + buttons.append(button) + } + bar.items = buttons + toolbarScroll.addSubview(bar) + return bar + }() + + + func toggleFontBar() { + UIView.animate(withDuration: 1) { [self] in + if fontToolbar.isHidden { + fontToolbar.alpha = 1 + toolbarScroll.contentSize.width = fontToolbar.bounds.size.width + } else { + fontToolbar.alpha = 0 + toolbarScroll.contentSize.width = toolbar.frame.size.width + } + fontToolbar.isHidden = !fontToolbar.isHidden + toolbar.isHidden = !fontToolbar.isHidden + } + } + public override init(frame: CGRect) { toolbarScroll = UIScrollView() toolbar = UIToolbar() diff --git a/RichEditorView/Classes/RichEditorView.swift b/RichEditorView/Classes/RichEditorView.swift index 5c5ccf15..8718ace7 100644 --- a/RichEditorView/Classes/RichEditorView.swift +++ b/RichEditorView/Classes/RichEditorView.swift @@ -48,7 +48,9 @@ import UIKit /// Defaults to nil open override var inputAccessoryView: UIView? { get { return webView.cjw_inputAccessoryView } - set { webView.cjw_inputAccessoryView = newValue } + set { + webView.cjw_inputAccessoryView = newValue + } } /// The internal UIWebView that is used to display the text. @@ -245,8 +247,18 @@ import UIKit runJS("RE.redo();") } + + public func setFont(_ font: RichEditorFontOption) { + guard let iav = inputAccessoryView as? RichEditorToolbar else { return } + iav.toggleFontBar() +// runJS + } + + public func setCode() { - runJS("RE.setCode();") +// runJS("RE.setCode();") + guard let iav = inputAccessoryView as? RichEditorToolbar else { return } + iav.toggleFontBar() } public func bold() { From ff46b06e1ac9a3c284cc23a0fc158806c87d5c54 Mon Sep 17 00:00:00 2001 From: Engin Date: Mon, 16 Aug 2021 17:49:45 +0300 Subject: [PATCH 05/11] added all required features --- RichEditorView.xcodeproj/project.pbxproj | 28 +++ RichEditorView/Assets/editor/rich_editor.js | 44 +++- RichEditorView/Assets/icons/back.png | Bin 0 -> 100 bytes RichEditorView/Assets/icons/blockQuote.png | Bin 0 -> 99 bytes RichEditorView/Assets/icons/h.png | Bin 0 -> 304 bytes RichEditorView/Assets/icons/justify.png | Bin 0 -> 463 bytes RichEditorView/Assets/icons/justify_full.png | Bin 0 -> 178 bytes RichEditorView/Assets/icons/size.png | Bin 0 -> 263 bytes .../Classes/RichEditorOptionItem.swift | 230 +++++++++++++----- .../Classes/RichEditorToolbar.swift | 74 ++++-- RichEditorView/Classes/RichEditorView.swift | 54 +++- 11 files changed, 339 insertions(+), 91 deletions(-) create mode 100644 RichEditorView/Assets/icons/back.png create mode 100644 RichEditorView/Assets/icons/blockQuote.png create mode 100644 RichEditorView/Assets/icons/h.png create mode 100644 RichEditorView/Assets/icons/justify.png create mode 100644 RichEditorView/Assets/icons/justify_full.png create mode 100644 RichEditorView/Assets/icons/size.png diff --git a/RichEditorView.xcodeproj/project.pbxproj b/RichEditorView.xcodeproj/project.pbxproj index 96ea45fe..66105c64 100644 --- a/RichEditorView.xcodeproj/project.pbxproj +++ b/RichEditorView.xcodeproj/project.pbxproj @@ -8,6 +8,13 @@ /* Begin PBXBuildFile section */ 284EE05E26C56851003E3F96 /* code.png in Resources */ = {isa = PBXBuildFile; fileRef = 284EE05D26C56851003E3F96 /* code.png */; }; + 28D2F19326CAB26800292922 /* back.png in Resources */ = {isa = PBXBuildFile; fileRef = 28D2F18C26CAB26700292922 /* back.png */; }; + 28D2F19426CAB26800292922 /* justify.png in Resources */ = {isa = PBXBuildFile; fileRef = 28D2F18D26CAB26700292922 /* justify.png */; }; + 28D2F19526CAB26800292922 /* size.png in Resources */ = {isa = PBXBuildFile; fileRef = 28D2F18E26CAB26700292922 /* size.png */; }; + 28D2F19626CAB26800292922 /* justify_full.png in Resources */ = {isa = PBXBuildFile; fileRef = 28D2F18F26CAB26700292922 /* justify_full.png */; }; + 28D2F19726CAB26800292922 /* blockQuote.png in Resources */ = {isa = PBXBuildFile; fileRef = 28D2F19026CAB26800292922 /* blockQuote.png */; }; + 28D2F19826CAB26800292922 /* h.png in Resources */ = {isa = PBXBuildFile; fileRef = 28D2F19126CAB26800292922 /* h.png */; }; + 28D2F19926CAB26800292922 /* f.png in Resources */ = {isa = PBXBuildFile; fileRef = 28D2F19226CAB26800292922 /* f.png */; }; 39FC98FB1DC788A1008FE5DD /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39FC98F91DC788A1008FE5DD /* String+Extensions.swift */; }; 39FC98FC1DC788A1008FE5DD /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39FC98FA1DC788A1008FE5DD /* UIColor+Extensions.swift */; }; 947A71A11C0F9DED00BDF9FC /* UIView+Responder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 947A71A01C0F9DED00BDF9FC /* UIView+Responder.swift */; }; @@ -86,6 +93,13 @@ /* Begin PBXFileReference section */ 284EE05D26C56851003E3F96 /* code.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = code.png; sourceTree = ""; }; + 28D2F18C26CAB26700292922 /* back.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = back.png; sourceTree = ""; }; + 28D2F18D26CAB26700292922 /* justify.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = justify.png; sourceTree = ""; }; + 28D2F18E26CAB26700292922 /* size.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = size.png; sourceTree = ""; }; + 28D2F18F26CAB26700292922 /* justify_full.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = justify_full.png; sourceTree = ""; }; + 28D2F19026CAB26800292922 /* blockQuote.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = blockQuote.png; sourceTree = ""; }; + 28D2F19126CAB26800292922 /* h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = h.png; sourceTree = ""; }; + 28D2F19226CAB26800292922 /* f.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = f.png; sourceTree = ""; }; 39FC98F91DC788A1008FE5DD /* String+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "String+Extensions.swift"; path = "Classes/String+Extensions.swift"; sourceTree = ""; }; 39FC98FA1DC788A1008FE5DD /* UIColor+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIColor+Extensions.swift"; path = "Classes/UIColor+Extensions.swift"; sourceTree = ""; }; 947A71A01C0F9DED00BDF9FC /* UIView+Responder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+Responder.swift"; path = "Classes/UIView+Responder.swift"; sourceTree = ""; }; @@ -273,6 +287,13 @@ FBA6AB1D1AD3ED2D00721644 /* icons */ = { isa = PBXGroup; children = ( + 28D2F18C26CAB26700292922 /* back.png */, + 28D2F19026CAB26800292922 /* blockQuote.png */, + 28D2F19226CAB26800292922 /* f.png */, + 28D2F19126CAB26800292922 /* h.png */, + 28D2F18F26CAB26700292922 /* justify_full.png */, + 28D2F18D26CAB26700292922 /* justify.png */, + 28D2F18E26CAB26700292922 /* size.png */, FBA6AB1E1AD3ED2D00721644 /* bg_color.png */, FBA6AB1F1AD3ED2D00721644 /* bg_color@2x.png */, FBA6AB201AD3ED2D00721644 /* bold.png */, @@ -424,6 +445,7 @@ files = ( FBA6AB641AD3ED2D00721644 /* h6@2x.png in Resources */, FBA6AB541AD3ED2D00721644 /* bg_color@2x.png in Resources */, + 28D2F19326CAB26800292922 /* back.png in Resources */, FBA6AB731AD3ED2D00721644 /* outdent.png in Resources */, FBA6AB591AD3ED2D00721644 /* h1.png in Resources */, FBA6AB691AD3ED2D00721644 /* insert_link.png in Resources */, @@ -435,15 +457,20 @@ FBA6AB7A1AD3ED2D00721644 /* subscript@2x.png in Resources */, FBA6AB5F1AD3ED2D00721644 /* h4.png in Resources */, FBA6AB681AD3ED2D00721644 /* insert_image@2x.png in Resources */, + 28D2F19626CAB26800292922 /* justify_full.png in Resources */, FBA6AB651AD3ED2D00721644 /* indent.png in Resources */, FBA6AB5D1AD3ED2D00721644 /* h3.png in Resources */, FBA6AB631AD3ED2D00721644 /* h6.png in Resources */, + 28D2F19926CAB26800292922 /* f.png in Resources */, FBA6AB561AD3ED2D00721644 /* bold@2x.png in Resources */, + 28D2F19826CAB26800292922 /* h.png in Resources */, FBA6AB6E1AD3ED2D00721644 /* justify_center@2x.png in Resources */, + 28D2F19726CAB26800292922 /* blockQuote.png in Resources */, FBA6AB5A1AD3ED2D00721644 /* h1@2x.png in Resources */, 284EE05E26C56851003E3F96 /* code.png in Resources */, FBA6AB721AD3ED2D00721644 /* justify_right@2x.png in Resources */, FBA6AB7D1AD3ED2D00721644 /* text_color.png in Resources */, + 28D2F19426CAB26800292922 /* justify.png in Resources */, FBA6AB621AD3ED2D00721644 /* h5@2x.png in Resources */, FBA6AB5C1AD3ED2D00721644 /* h2@2x.png in Resources */, FBA6AB6B1AD3ED2D00721644 /* italic.png in Resources */, @@ -458,6 +485,7 @@ FBA6AB7E1AD3ED2D00721644 /* text_color@2x.png in Resources */, FBA6AB811AD3ED2D00721644 /* undo.png in Resources */, FBA6AB511AD3ED2D00721644 /* rich_editor.js in Resources */, + 28D2F19526CAB26800292922 /* size.png in Resources */, FBA6AB521AD3ED2D00721644 /* style.css in Resources */, FBA6AB601AD3ED2D00721644 /* h4@2x.png in Resources */, FBA6AB581AD3ED2D00721644 /* clear@2x.png in Resources */, diff --git a/RichEditorView/Assets/editor/rich_editor.js b/RichEditorView/Assets/editor/rich_editor.js index b6f9035c..88a6c37e 100644 --- a/RichEditorView/Assets/editor/rich_editor.js +++ b/RichEditorView/Assets/editor/rich_editor.js @@ -134,7 +134,30 @@ RE.removeFormat = function() { }; RE.setFontSize = function(size) { - RE.editor.style.fontSize = size; + var sel = window.getSelection(); + if (sel.rangeCount) { + // Creates a new element, and insert the selected text with the chosen font inside + var e = document.createElement('span'); + e.style.fontSize = size; + e.innerHTML = sel.toString(); + var range = sel.getRangeAt(0); + range.deleteContents(); // Deletes selected text… + range.insertNode(e); // … and inserts the new element at its place + } +}; + + +RE.setFont = function(font) { + var sel = window.getSelection(); + if (sel.rangeCount) { + // Creates a new element, and insert the selected text with the chosen font inside + var e = document.createElement('span'); + e.style.fontFamily = font; + e.innerHTML = sel.toString(); + var range = sel.getRangeAt(0); + range.deleteContents(); // Deletes selected text… + range.insertNode(e); // … and inserts the new element at its place + } }; RE.setBackgroundColor = function(color) { @@ -231,6 +254,10 @@ RE.setJustifyRight = function() { document.execCommand('justifyRight', false, null); }; +RE.setJustifyFull = function() { + document.execCommand('justifyFull', false, null); +}; + RE.getLineHeight = function() { return RE.editor.style.lineHeight; }; @@ -249,8 +276,21 @@ RE.insertImage = function(url, alt) { RE.callback("input"); }; +RE.setCode = function() { + if(window.getSelection().toString() != "") { + var code = window.getSelection().toString().replace(//ig, '>'); + var html ='

' + code +'

' + } + RE.insertHTML(html); +} + RE.setBlockquote = function() { - document.execCommand('formatBlock', false, '
'); + // for all use: +// document.execCommand('formatBlock', false, '
'); + if(window.getSelection().toString() != "") { + var html = '

' + window.getSelection().toString() + '


'; + RE.insertHTML(html); + } }; RE.insertHTML = function(html) { diff --git a/RichEditorView/Assets/icons/back.png b/RichEditorView/Assets/icons/back.png new file mode 100644 index 0000000000000000000000000000000000000000..074cb0680f15d363af1a00310ba14e07efa2faa3 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1ZBG}+5R22v2@)9r{4FY)|M^>7 xmuS`>T41$m&bm`4FBq(9?ThNlnBlsTk->MJgSC@(-T|OC22WQ%mvv4FO#ti|9p(T4 literal 0 HcmV?d00001 diff --git a/RichEditorView/Assets/icons/blockQuote.png b/RichEditorView/Assets/icons/blockQuote.png new file mode 100644 index 0000000000000000000000000000000000000000..e1c2703d849be65ec52166b13da16b38fa825e78 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1El(H65R22v2@zopr0DIUQ0{{R3 literal 0 HcmV?d00001 diff --git a/RichEditorView/Assets/icons/h.png b/RichEditorView/Assets/icons/h.png new file mode 100644 index 0000000000000000000000000000000000000000..213390abea0c6c8542205456e9a81d031c7cd920 GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBI14-?iy0WWg+Z8+Vb&Z8pde#$ zkh>GZx^prwfgF}}M_)$E)e-c@N{G*;Ojv*C{Z>MkMI^@99R`2@eis$w`zdpML z{RgY9tt@w1TJBmgnR8CWt|$Hr3YPv?)o{#$r!)Ep`e1wE4*7JKHB( zO!=c&xY2CQfsIpNc-571ymWu#eb30rJH(AEa>)c&uE-GeBXK>oenRp^Z>9Z|oOu5w zA6e8ox#I%wAI_Bl?CgSybKT2}-tze^+}K^ktG+p}`qlK*P3l+jKa0DmC>_~W(=jJi x>?-HR^9pMh-d8=o&!X-3mTz|sn|Z387k~LqxHW3Ij6cvr44$rjF6*2UngDVpbGZNj literal 0 HcmV?d00001 diff --git a/RichEditorView/Assets/icons/justify.png b/RichEditorView/Assets/icons/justify.png new file mode 100644 index 0000000000000000000000000000000000000000..bb5cdae7ba3fe1091bb32b16081ee99e69a1046a GIT binary patch literal 463 zcmV;=0WkiFP)3G%%)wkzK~2*hZQHI%5zN6{ zV%!u1TvZ&$rt7-bq<|zz9>8^k%h{wLSB0a&@lFb;>-xhmjP*Lq^ZeFvoO@CL)*o1w zbwfgjdk=q&y@%i64x=clJB|JTDm|7+WRd;-Mk3$m^sV>JK(002ovPDHLk FV1nJ3!Dj#f literal 0 HcmV?d00001 diff --git a/RichEditorView/Assets/icons/justify_full.png b/RichEditorView/Assets/icons/justify_full.png new file mode 100644 index 0000000000000000000000000000000000000000..512cbe58531d3e441a3a9287b2e9d693c267c78a GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^qChOd!3HFgyvvM%6lZ})WHAE+w=f7ZGR&GI0Tg5` z4sv&5Sa(k5C6L3C?&#~tz_78O`%fY(knis4;uuoF`1aC9UIqmYmy3sY@L5|(E#Aq@ z-N}4o#%6;LLRvyxpN`(;P2pYX`KP2|&2gRyZx;(^dLH!;|5*RXsxEZv<#(QcxLbD# VHcX0MxDIF}gQu&X%Q~loCIF|tHe&z) literal 0 HcmV?d00001 diff --git a/RichEditorView/Assets/icons/size.png b/RichEditorView/Assets/icons/size.png new file mode 100644 index 0000000000000000000000000000000000000000..96f46fb35c604fe0685db9ed49c4d385eff65722 GIT binary patch literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zoCO|{#S9GG!XV7ZFl&wkP>``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eB{v1yi$B+ufw^MKPwkQa=zR%m%pquD@Lud=L z_aQDFNAHconvU85LhR0Jb`2{6jnyqVPd%O+A_0MmN;9i{W?{HkAmdbYl!P2tT+hK3032f2HWJqNmz!PC{xWt~$( F69CEpT$TU; literal 0 HcmV?d00001 diff --git a/RichEditorView/Classes/RichEditorOptionItem.swift b/RichEditorView/Classes/RichEditorOptionItem.swift index 2f13d0ed..de53c38d 100644 --- a/RichEditorView/Classes/RichEditorOptionItem.swift +++ b/RichEditorView/Classes/RichEditorOptionItem.swift @@ -50,97 +50,203 @@ public struct RichEditorOptionItem: RichEditorOption { } } +public enum RichEditorHeadingOption: RichEditorOption { + + case back + case header(Int) -public enum RichEditorTextSizeOption: RichEditorOption { + public static let all: [RichEditorHeadingOption] = [ .back, .header(1), .header(2), .header(3), .header(4), .header(5), .header(6),] public var image: UIImage? { - return nil + var name = "" + switch self { + case .header(let h): name = "h\(h)" + case .back: name = "back" + } + let bundle = Bundle(for: RichEditorToolbar.self) + return UIImage(named: name, in: bundle, compatibleWith: nil) } public var title: String { - return "" + var name = "" + switch self { + case .header(let h): name = "h\(h)" + case .back: name = "back" + } + return name } - public func action(_ editor: RichEditorToolbar) { - + public func action(_ toolbar: RichEditorToolbar) { + switch self { + case .header(let h): toolbar.editor?.header(h) + case .back: toolbar.editor?.goBackFromHeadlines() + } + } +} + +public enum RichEditorTextSizeOption: Int, RichEditorOption { + + case back = 0 + case pt8 = 8 + case pt10 = 10 + case pt12 = 12 + case pt14 = 14 + case pt18 = 18 + case pt24 = 24 + case pt36 = 36 + + public static let all: [RichEditorTextSizeOption] = [ .back, .pt10, .pt12, .pt14, .pt18, .pt24, .pt36,] + + public var image: UIImage? { + if self == .back { + let bundle = Bundle(for: RichEditorToolbar.self) + return UIImage(named: "back", in: bundle, compatibleWith: nil) + } else { + return nil + } + } + + public var title: String { + if self == .back { + return "back" + } + let str = String(self.rawValue) + "pt " + return str + } + + public func action(_ toolbar: RichEditorToolbar) { + toolbar.editor?.setFontSize(self.rawValue) } - } -public enum RichEditorFontOption: RichEditorOption { +public enum RichEditorFontOption: String, RichEditorOption { - case Ariel - case CourierNew - case Georgia - case Impact - case LucidaConsole - case Tahoma - case TimesNewRoman - case Verdana + case back = "back" + case Ariel = "Ariel" + case CourierNew = "CourierNew" + case Georgia = "Georgia" + case Impact = "Impact" + case LucidaConsole = "LucidaConsole" + case Tahoma = "Tahoma" + case TimesNewRoman = "TimesNewRoman" + case Verdana = "Verdana" public static let all: [RichEditorFontOption] = [ - .Ariel, .CourierNew, .Georgia, .Impact, .LucidaConsole, .Tahoma, .TimesNewRoman, .Verdana, + .back, .Ariel, .CourierNew, .Georgia, .Impact, .LucidaConsole, .Tahoma, .TimesNewRoman, .Verdana, ] public var image: UIImage? { + if self == .back { + let bundle = Bundle(for: RichEditorToolbar.self) + return UIImage(named: "back", in: bundle, compatibleWith: nil) + } return nil } public var title: String { - switch self { - case .Ariel: return "Ariel" - case .CourierNew: return "Courier New" - case .Georgia: return "Georgia" - case .Impact: return "Impact" - case .LucidaConsole: return "Lucida Console" - case .Tahoma: return "Tahoma" - case .TimesNewRoman: return "Times New Roman" - case .Verdana: return "Verdana" - } + return self.rawValue } public func action(_ toolbar: RichEditorToolbar) { - toolbar.editor?.setFont(self) + toolbar.editor?.setFont(self.rawValue) } } +public enum RichEditorAllignmentOption: RichEditorOption { + + case back + case indent + case outdent + case orderedList + case unorderedList + case alignLeft + case alignCenter + case alignRight + case justify + + + public static let all: [RichEditorAllignmentOption] = [ + .back, .indent, .outdent, .orderedList, .unorderedList, + .alignLeft, .alignCenter, .alignRight,.justify, + ] + + public var image: UIImage? { + var name = "" + switch self { + case .back: name = "back" + case .indent: name = "indent" + case .outdent: name = "outdent" + case .orderedList: name = "ordered_list" + case .unorderedList: name = "unordered_list" + case .alignLeft: name = "justify_left" + case .alignCenter: name = "justify_center" + case .alignRight: name = "justify_right" + case .justify: name = "justify_full" + } + let bundle = Bundle(for: RichEditorToolbar.self) + return UIImage(named: name, in: bundle, compatibleWith: nil) + } + + public var title: String { + switch self { + case .back: return NSLocalizedString("back", comment: "") + case .indent: return NSLocalizedString("Indent", comment: "") + case .outdent: return NSLocalizedString("Outdent", comment: "") + case .orderedList: return NSLocalizedString("Ordered List", comment: "") + case .unorderedList: return NSLocalizedString("Unordered List", comment: "") + case .alignLeft: return NSLocalizedString("Left", comment: "") + case .alignCenter: return NSLocalizedString("Center", comment: "") + case .alignRight: return NSLocalizedString("Right", comment: "") + case .justify: return NSLocalizedString("Justify", comment: "") + } + } + + public func action(_ toolbar: RichEditorToolbar) { + switch self { + case .back: toolbar.editor?.goBackFromAllignments() + case .indent: toolbar.editor?.indent() + case .outdent: toolbar.editor?.outdent() + case .orderedList: toolbar.editor?.orderedList() + case .unorderedList: toolbar.editor?.unorderedList() + case .alignLeft: toolbar.editor?.alignLeft() + case .alignCenter: toolbar.editor?.alignCenter() + case .alignRight: toolbar.editor?.alignRight() + case .justify: toolbar.editor?.justifyFull() + } + } + +} /// RichEditorOptions is an enum of standard editor actions public enum RichEditorDefaultOption: RichEditorOption { case clear - case code case undo case redo case bold case italic + case size + case header + case font + case blockquote + case code case `subscript` case superscript case strike case underline case textColor case textBackgroundColor - case header(Int) - case indent - case outdent - case orderedList - case unorderedList - case alignLeft - case alignCenter - case alignRight + case allignment case image case link public static let all: [RichEditorDefaultOption] = [ - .clear,.code, - .undo, .redo, .bold, .italic, + .clear, .undo, .redo, .bold, .italic, .header, .size, .font, .subscript, .superscript, .strike, .underline, - .textColor, .textBackgroundColor, - .header(1), .header(2), .header(3), .header(4), .header(5), .header(6), - .indent, outdent, orderedList, unorderedList, - .alignLeft, .alignCenter, .alignRight, .image, .link + .textColor, .textBackgroundColor, .allignment, + .code, .blockquote,.image, .link ] // MARK: RichEditorOption @@ -150,6 +256,7 @@ public enum RichEditorDefaultOption: RichEditorOption { switch self { case .clear: name = "clear" case .code: name = "code" + case .blockquote: name = "blockQuote" case .undo: name = "undo" case .redo: name = "redo" case .bold: name = "bold" @@ -160,16 +267,13 @@ public enum RichEditorDefaultOption: RichEditorOption { case .underline: name = "underline" case .textColor: name = "text_color" case .textBackgroundColor: name = "bg_color" - case .header(let h): name = "h\(h)" - case .indent: name = "indent" - case .outdent: name = "outdent" - case .orderedList: name = "ordered_list" - case .unorderedList: name = "unordered_list" - case .alignLeft: name = "justify_left" - case .alignCenter: name = "justify_center" - case .alignRight: name = "justify_right" + case .header: name = "h" + case .image: name = "insert_image" case .link: name = "insert_link" + case .size: name = "size" + case .font: name = "f" + case .allignment: name = "justify" } let bundle = Bundle(for: RichEditorToolbar.self) @@ -182,6 +286,7 @@ public enum RichEditorDefaultOption: RichEditorOption { case .undo: return NSLocalizedString("Undo", comment: "") case .redo: return NSLocalizedString("Redo", comment: "") case .code: return NSLocalizedString("Code Block", comment: "") + case .blockquote: return NSLocalizedString("blockQuote", comment: "") case .bold: return NSLocalizedString("Bold", comment: "") case .italic: return NSLocalizedString("Italic", comment: "") case .subscript: return NSLocalizedString("Sub", comment: "") @@ -190,16 +295,12 @@ public enum RichEditorDefaultOption: RichEditorOption { case .underline: return NSLocalizedString("Underline", comment: "") case .textColor: return NSLocalizedString("Color", comment: "") case .textBackgroundColor: return NSLocalizedString("BG Color", comment: "") - case .header(let h): return NSLocalizedString("H\(h)", comment: "") - case .indent: return NSLocalizedString("Indent", comment: "") - case .outdent: return NSLocalizedString("Outdent", comment: "") - case .orderedList: return NSLocalizedString("Ordered List", comment: "") - case .unorderedList: return NSLocalizedString("Unordered List", comment: "") - case .alignLeft: return NSLocalizedString("Left", comment: "") - case .alignCenter: return NSLocalizedString("Center", comment: "") - case .alignRight: return NSLocalizedString("Right", comment: "") + case .header: return NSLocalizedString("H", comment: "") + case .allignment: return NSLocalizedString("Allignment", comment: "") case .image: return NSLocalizedString("Image", comment: "") case .link: return NSLocalizedString("Link", comment: "") + case .size: return NSLocalizedString("Size", comment: "") + case .font: return NSLocalizedString("Font", comment: "") } } @@ -217,16 +318,13 @@ public enum RichEditorDefaultOption: RichEditorOption { case .underline: toolbar.editor?.underline() case .textColor: toolbar.delegate?.richEditorToolbarChangeTextColor?(toolbar) case .textBackgroundColor: toolbar.delegate?.richEditorToolbarChangeBackgroundColor?(toolbar) - case .header(let h): toolbar.editor?.header(h) - case .indent: toolbar.editor?.indent() - case .outdent: toolbar.editor?.outdent() - case .orderedList: toolbar.editor?.orderedList() - case .unorderedList: toolbar.editor?.unorderedList() - case .alignLeft: toolbar.editor?.alignLeft() - case .alignCenter: toolbar.editor?.alignCenter() - case .alignRight: toolbar.editor?.alignRight() + case .header: toolbar.editor?.showHeader() + case .allignment: toolbar.editor?.showAllignments() case .image: toolbar.delegate?.richEditorToolbarInsertImage?(toolbar) case .link: toolbar.delegate?.richEditorToolbarInsertLink?(toolbar) + case .size: toolbar.editor?.showTextSize() + case .font: toolbar.editor?.showFonts() + case .blockquote: toolbar.editor?.blockquote() } } } diff --git a/RichEditorView/Classes/RichEditorToolbar.swift b/RichEditorView/Classes/RichEditorToolbar.swift index e2b64d75..8f00c077 100644 --- a/RichEditorView/Classes/RichEditorToolbar.swift +++ b/RichEditorView/Classes/RichEditorToolbar.swift @@ -73,41 +73,85 @@ import UIKit private var toolbar: UIToolbar private var backgroundToolbar: UIToolbar + + lazy var headlineToolbar: UIToolbar = { + let bar = UIToolbar(frame: CGRect(x: 0, y:0, width: bounds.width, height: 44)) + var buttons = [UIBarButtonItem]() + let opt = RichEditorHeadingOption.all + let headLineBar = createToolBar(bar: bar,options: opt) + return headLineBar + }() + lazy var fontToolbar: UIToolbar = { - let bar = UIToolbar(frame: CGRect(x: 0, y:0, width: 800, height: 44)) - bar.isHidden = true - bar.autoresizingMask = .flexibleWidth - bar.alpha = 0 + let bar = UIToolbar(frame: CGRect(x: 0, y:0, width: 820, height: 44)) + var buttons = [UIBarButtonItem]() + let opt = RichEditorFontOption.all + let fontBar = createToolBar(bar: bar,options: opt) + return fontBar + }() + + + lazy var allignmentToolbar: UIToolbar = { + let bar = UIToolbar(frame: CGRect(x: 0, y:0, width: bounds.width, height: 44)) + var buttons = [UIBarButtonItem]() + let opt = RichEditorAllignmentOption.all + let alignBar = createToolBar(bar: bar,options: opt) + return alignBar + }() + + lazy var sizeToolbar: UIToolbar = { + var width:CGFloat = 400 + if bounds.width > 400 { + width = bounds.width + } + + let bar = UIToolbar(frame: CGRect(x: 0, y:0, width: width, height: 44)) var buttons = [UIBarButtonItem]() - let options = RichEditorFontOption.all + let opt = RichEditorTextSizeOption.all + let fontBar = createToolBar(bar: bar,options: opt) + return fontBar + }() + + + func createToolBar(bar: UIToolbar,options: [RichEditorOption]) -> UIToolbar { + bar.isHidden = true + bar.autoresizingMask = .flexibleWidth + bar.alpha = 0 + var buttons = [UIBarButtonItem]() for option in options { let handler = { [weak self] in if let strongSelf = self { option.action(strongSelf) } } + if let image = option.image { + let button = RichBarButtonItem(image: image, handler: handler) + buttons.append(button) + } else { let title = option.title let button = RichBarButtonItem(title: title, handler: handler) buttons.append(button) + } } bar.items = buttons toolbarScroll.addSubview(bar) return bar - }() + } - func toggleFontBar() { - UIView.animate(withDuration: 1) { [self] in - if fontToolbar.isHidden { - fontToolbar.alpha = 1 - toolbarScroll.contentSize.width = fontToolbar.bounds.size.width + func toggleBars(bar: UIToolbar) { + UIView.animate(withDuration: 0.5) { [self] in + if bar.isHidden { + bar.alpha = 1 + toolbarScroll.contentSize.width = bar.bounds.size.width } else { - fontToolbar.alpha = 0 + bar.alpha = 0 toolbarScroll.contentSize.width = toolbar.frame.size.width } - fontToolbar.isHidden = !fontToolbar.isHidden - toolbar.isHidden = !fontToolbar.isHidden + bar.isHidden = !bar.isHidden + toolbar.isHidden = !bar.isHidden + toolbarScroll.setContentOffset(.zero, animated: true) } } @@ -185,7 +229,7 @@ import UIKit if width < frame.size.width { toolbar.frame.size.width = frame.size.width } else { - toolbar.frame.size.width = width + toolbar.frame.size.width = width + 10 //padding } toolbar.frame.size.height = 44 toolbarScroll.contentSize.width = width diff --git a/RichEditorView/Classes/RichEditorView.swift b/RichEditorView/Classes/RichEditorView.swift index 8718ace7..3ae58d9d 100644 --- a/RichEditorView/Classes/RichEditorView.swift +++ b/RichEditorView/Classes/RichEditorView.swift @@ -232,7 +232,11 @@ import UIKit } public func setFontSize(_ size: Int) { - runJS("RE.setFontSize('\(size)px');") + if size != 0 { + runJS("RE.setFontSize('\(size)px');") + } + guard let iav = inputAccessoryView as? RichEditorToolbar else { return } + iav.toggleBars(bar: iav.sizeToolbar) } public func setEditorBackgroundColor(_ color: UIColor) { @@ -246,21 +250,50 @@ import UIKit public func redo() { runJS("RE.redo();") } + - - public func setFont(_ font: RichEditorFontOption) { + public func goBackFromHeadlines() { guard let iav = inputAccessoryView as? RichEditorToolbar else { return } - iav.toggleFontBar() -// runJS + iav.toggleBars(bar: iav.headlineToolbar) } + public func goBackFromAllignments() { + guard let iav = inputAccessoryView as? RichEditorToolbar else { return } + iav.toggleBars(bar: iav.allignmentToolbar) + } - public func setCode() { -// runJS("RE.setCode();") + public func setFont(_ font: String) { + if font != "back" { + runJS("RE.setFont('\(font)');") + } + guard let iav = inputAccessoryView as? RichEditorToolbar else { return } + iav.toggleBars(bar: iav.fontToolbar) + } + + public func showTextSize() { + guard let iav = inputAccessoryView as? RichEditorToolbar else { return } + iav.toggleBars(bar: iav.sizeToolbar) + } + + public func showHeader() { guard let iav = inputAccessoryView as? RichEditorToolbar else { return } - iav.toggleFontBar() + iav.toggleBars(bar: iav.headlineToolbar) } + public func showFonts() { + guard let iav = inputAccessoryView as? RichEditorToolbar else { return } + iav.toggleBars(bar: iav.fontToolbar) + } + + public func showAllignments() { + guard let iav = inputAccessoryView as? RichEditorToolbar else { return } + iav.toggleBars(bar: iav.allignmentToolbar) + } + + public func setCode() { + runJS("RE.setCode();") + } + public func bold() { runJS("RE.setBold();") } @@ -302,6 +335,7 @@ import UIKit public func header(_ h: Int) { runJS("RE.setHeading('\(h)');") + } public func indent() { @@ -336,6 +370,10 @@ import UIKit runJS("RE.setJustifyRight();") } + public func justifyFull() { + runJS("RE.setJustifyRight();") + } + public func insertImage(_ url: String, alt: String) { runJS("RE.prepareInsert();") runJS("RE.insertImage('\(url.escaped)', '\(alt.escaped)');") From 8483ebd9b4b038a869770d39f03fb640540f53a6 Mon Sep 17 00:00:00 2001 From: Engin Date: Mon, 16 Aug 2021 19:05:08 +0300 Subject: [PATCH 06/11] toggle added for headline --- RichEditorView/Assets/icons/f.png | Bin 0 -> 278 bytes RichEditorView/Classes/RichEditorOptionItem.swift | 4 ++-- RichEditorView/Classes/RichEditorView.swift | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) create mode 100644 RichEditorView/Assets/icons/f.png diff --git a/RichEditorView/Assets/icons/f.png b/RichEditorView/Assets/icons/f.png new file mode 100644 index 0000000000000000000000000000000000000000..12ba06ee3bd15619491848c252d0f4bb046c1b54 GIT binary patch literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBI14-?iy0WWg+Z8+Vb&Z8pde#$ zkh>GZx^prwfgF}}M_)$E)e-c@N{MDW=jv*C{Z?Es=Z8i{KeK1|aNOY#M^ODoc zW;U?iXl9+!z@?R=sM6i^IZ^uKXS6{{;Z|)b|rV_33E!1bhrFroV^KW0^ zWs=QXkvwlgwW#PaM|163<}xmm*Aoj4?37UDQAt$bWcJ*0U19l`S5NGJx=c4_+Hgp~ VK=AE{XFz8&c)I$ztaD0e0sulAV3+^^ literal 0 HcmV?d00001 diff --git a/RichEditorView/Classes/RichEditorOptionItem.swift b/RichEditorView/Classes/RichEditorOptionItem.swift index de53c38d..f2cdc995 100644 --- a/RichEditorView/Classes/RichEditorOptionItem.swift +++ b/RichEditorView/Classes/RichEditorOptionItem.swift @@ -79,7 +79,7 @@ public enum RichEditorHeadingOption: RichEditorOption { public func action(_ toolbar: RichEditorToolbar) { switch self { case .header(let h): toolbar.editor?.header(h) - case .back: toolbar.editor?.goBackFromHeadlines() + case .back: toolbar.editor?.toggleHeadlines() } } } @@ -206,7 +206,7 @@ public enum RichEditorAllignmentOption: RichEditorOption { public func action(_ toolbar: RichEditorToolbar) { switch self { - case .back: toolbar.editor?.goBackFromAllignments() + case .back: toolbar.editor?.toggleAllignments() case .indent: toolbar.editor?.indent() case .outdent: toolbar.editor?.outdent() case .orderedList: toolbar.editor?.orderedList() diff --git a/RichEditorView/Classes/RichEditorView.swift b/RichEditorView/Classes/RichEditorView.swift index 3ae58d9d..54579d8f 100644 --- a/RichEditorView/Classes/RichEditorView.swift +++ b/RichEditorView/Classes/RichEditorView.swift @@ -252,12 +252,12 @@ import UIKit } - public func goBackFromHeadlines() { + public func toggleHeadlines() { guard let iav = inputAccessoryView as? RichEditorToolbar else { return } iav.toggleBars(bar: iav.headlineToolbar) } - public func goBackFromAllignments() { + public func toggleAllignments() { guard let iav = inputAccessoryView as? RichEditorToolbar else { return } iav.toggleBars(bar: iav.allignmentToolbar) } @@ -276,8 +276,7 @@ import UIKit } public func showHeader() { - guard let iav = inputAccessoryView as? RichEditorToolbar else { return } - iav.toggleBars(bar: iav.headlineToolbar) + toggleHeadlines() } public func showFonts() { @@ -335,7 +334,7 @@ import UIKit public func header(_ h: Int) { runJS("RE.setHeading('\(h)');") - + toggleHeadlines() } public func indent() { From ef41304d38100d1caae87e46131344570f8a8af2 Mon Sep 17 00:00:00 2001 From: Engin Date: Mon, 16 Aug 2021 20:01:25 +0300 Subject: [PATCH 07/11] toolbar fixed size --- .../Classes/RichEditorToolbar.swift | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/RichEditorView/Classes/RichEditorToolbar.swift b/RichEditorView/Classes/RichEditorToolbar.swift index 8f00c077..a1888bb1 100644 --- a/RichEditorView/Classes/RichEditorToolbar.swift +++ b/RichEditorView/Classes/RichEditorToolbar.swift @@ -70,7 +70,7 @@ import UIKit } private var toolbarScroll: UIScrollView - private var toolbar: UIToolbar + private var defautToolbar: UIToolbar private var backgroundToolbar: UIToolbar @@ -147,17 +147,18 @@ import UIKit toolbarScroll.contentSize.width = bar.bounds.size.width } else { bar.alpha = 0 - toolbarScroll.contentSize.width = toolbar.frame.size.width + // this should be defautToolbar.frame.width, temp fix for bug: + toolbarScroll.contentSize.width = 750 } bar.isHidden = !bar.isHidden - toolbar.isHidden = !bar.isHidden + defautToolbar.isHidden = !bar.isHidden toolbarScroll.setContentOffset(.zero, animated: true) } } public override init(frame: CGRect) { toolbarScroll = UIScrollView() - toolbar = UIToolbar() + defautToolbar = UIToolbar() backgroundToolbar = UIToolbar() super.init(frame: frame) setup() @@ -165,7 +166,7 @@ import UIKit public required init?(coder aDecoder: NSCoder) { toolbarScroll = UIScrollView() - toolbar = UIToolbar() + defautToolbar = UIToolbar() backgroundToolbar = UIToolbar() super.init(coder: aDecoder) setup() @@ -178,10 +179,10 @@ import UIKit backgroundToolbar.frame = bounds backgroundToolbar.autoresizingMask = [.flexibleHeight, .flexibleWidth] - toolbar.autoresizingMask = .flexibleWidth - toolbar.backgroundColor = .clear - toolbar.setBackgroundImage(UIImage(), forToolbarPosition: .any, barMetrics: .default) - toolbar.setShadowImage(UIImage(), forToolbarPosition: .any) + defautToolbar.autoresizingMask = .flexibleWidth + defautToolbar.backgroundColor = .clear + defautToolbar.setBackgroundImage(UIImage(), forToolbarPosition: .any, barMetrics: .default) + defautToolbar.setShadowImage(UIImage(), forToolbarPosition: .any) toolbarScroll.frame = bounds toolbarScroll.autoresizingMask = [.flexibleHeight, .flexibleWidth] @@ -189,7 +190,7 @@ import UIKit toolbarScroll.showsVerticalScrollIndicator = false toolbarScroll.backgroundColor = .clear - toolbarScroll.addSubview(toolbar) + toolbarScroll.addSubview(defautToolbar) addSubview(backgroundToolbar) addSubview(toolbarScroll) @@ -214,7 +215,7 @@ import UIKit buttons.append(button) } } - toolbar.items = buttons + defautToolbar.items = buttons let defaultIconWidth: CGFloat = 28 let barButtonItemMargin: CGFloat = 11 @@ -227,11 +228,11 @@ import UIKit } if width < frame.size.width { - toolbar.frame.size.width = frame.size.width + defautToolbar.frame.size.width = frame.size.width } else { - toolbar.frame.size.width = width + 10 //padding + defautToolbar.frame.size.width = width + 10 //padding } - toolbar.frame.size.height = 44 + defautToolbar.frame.size.height = 44 toolbarScroll.contentSize.width = width } From c7ca87f87c11cccb1a6dae9559664d6423d0b73e Mon Sep 17 00:00:00 2001 From: Engin Date: Wed, 18 Aug 2021 17:33:49 +0300 Subject: [PATCH 08/11] methods working --- RichEditorView/Assets/icons/done.png | Bin 0 -> 280 bytes .../Classes/RichEditorToolbar.swift | 49 +++++++++++++++--- RichEditorView/Classes/RichEditorView.swift | 16 +++++- .../Pods/Pods.xcodeproj/project.pbxproj | 35 +++++++------ .../RichEditorViewSample/ViewController.swift | 25 ++++----- 5 files changed, 88 insertions(+), 37 deletions(-) create mode 100644 RichEditorView/Assets/icons/done.png diff --git a/RichEditorView/Assets/icons/done.png b/RichEditorView/Assets/icons/done.png new file mode 100644 index 0000000000000000000000000000000000000000..b884c0e03d8a16162d6db050fd615065af07ae75 GIT binary patch literal 280 zcmV+z0q6dSP)Yx(ge<#)RdYu- Bool { + public func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool { // Handle pre-defined editor actions let callbackPrefix = "re-callback://" diff --git a/RichEditorViewSample/Pods/Pods.xcodeproj/project.pbxproj b/RichEditorViewSample/Pods/Pods.xcodeproj/project.pbxproj index 3a38b22a..06829d6d 100644 --- a/RichEditorViewSample/Pods/Pods.xcodeproj/project.pbxproj +++ b/RichEditorViewSample/Pods/Pods.xcodeproj/project.pbxproj @@ -19,6 +19,7 @@ 21A9B7FCC0D608BD65DE2AAEB9E2BD28 /* bg_color@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 46D119FA78DC9819A8493032125B2620 /* bg_color@2x.png */; }; 25DFDF691800BC06F20FF136543CB05A /* redo.png in Resources */ = {isa = PBXBuildFile; fileRef = 93287F33CC93CB4BE2EB94A7E6932D56 /* redo.png */; }; 26B674B1D5DD424360E1B6AB350F9840 /* style.css in Resources */ = {isa = PBXBuildFile; fileRef = 1672230420C54446C8D87D1F2A4C31DC /* style.css */; }; + 28BE08CF26CD4C06009FEF24 /* done.png in Resources */ = {isa = PBXBuildFile; fileRef = 28BE08CE26CD4C06009FEF24 /* done.png */; }; 2CE9FEA70AB67B34F2CFF606AAFC3C40 /* justify_left.png in Resources */ = {isa = PBXBuildFile; fileRef = 40634E726AC7B34435A3E907D32A5C7C /* justify_left.png */; }; 339A87EF9A671044103479E863C9BCA4 /* Pods-RichEditorViewSample-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 7980878382C0AB691C47F03DA0538E4D /* Pods-RichEditorViewSample-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34A1ABB01305D4836C844873604620BD /* insert_link.png in Resources */ = {isa = PBXBuildFile; fileRef = 4FAB2A52EE2F0E0BBBFA7406F553B118 /* insert_link.png */; }; @@ -95,41 +96,42 @@ /* Begin PBXFileReference section */ 047AADD0F93334158F1D9DF4A65F1690 /* bold.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = bold.png; sourceTree = ""; }; 0C19598CA9DC4254DAD2E60299544EEE /* underline@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "underline@2x.png"; sourceTree = ""; }; - 1077949CD2E04C6A64962AA4CAAFD184 /* LICENSE.md */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.md; sourceTree = ""; }; - 1271E747F5D9EEB8266B0E0F0D8285E6 /* Pods_RichEditorViewSample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_RichEditorViewSample.framework; path = "Pods-RichEditorViewSample.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1077949CD2E04C6A64962AA4CAAFD184 /* LICENSE.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = LICENSE.md; sourceTree = ""; }; + 1271E747F5D9EEB8266B0E0F0D8285E6 /* Pods_RichEditorViewSample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RichEditorViewSample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 13C70F08F9A188217D25A786931C6B4F /* Pods-RichEditorViewSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-RichEditorViewSample.release.xcconfig"; sourceTree = ""; }; - 14E29C85382435C544E1049690507DA2 /* Pods-RichEditorViewSample.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-RichEditorViewSample.modulemap"; sourceTree = ""; }; - 1672230420C54446C8D87D1F2A4C31DC /* style.css */ = {isa = PBXFileReference; includeInIndex = 1; path = style.css; sourceTree = ""; }; + 14E29C85382435C544E1049690507DA2 /* Pods-RichEditorViewSample.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-RichEditorViewSample.modulemap"; sourceTree = ""; }; + 1672230420C54446C8D87D1F2A4C31DC /* style.css */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.css; path = style.css; sourceTree = ""; }; 180421D0F4576D77B1E08CA2132BD24E /* subscript.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = subscript.png; sourceTree = ""; }; 19ABEBF2CFAC08E34E4FCAAF7FE83363 /* RichEditorView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RichEditorView-prefix.pch"; sourceTree = ""; }; 1DA527F8D0CC821E2D123B407B290476 /* undo@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "undo@2x.png"; sourceTree = ""; }; 25514417F0E67AC446ADC1943AD650BB /* RichEditorView.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RichEditorView.xcconfig; sourceTree = ""; }; - 25A38A9BA9BDB52FC3E88D49A58C33B3 /* rich_editor.js */ = {isa = PBXFileReference; includeInIndex = 1; path = rich_editor.js; sourceTree = ""; }; + 25A38A9BA9BDB52FC3E88D49A58C33B3 /* rich_editor.js */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.javascript; path = rich_editor.js; sourceTree = ""; }; + 28BE08CE26CD4C06009FEF24 /* done.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = done.png; sourceTree = ""; }; 2EDAE0C8992041C9DF22B7387230C7D5 /* strikethrough.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = strikethrough.png; sourceTree = ""; }; 34C2463E7C6EEC1D53284EFE2030A449 /* justify_center@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "justify_center@2x.png"; sourceTree = ""; }; - 3993FDE4880FB5D2EB58DC50BE4787B6 /* rich_editor_tests.html */ = {isa = PBXFileReference; includeInIndex = 1; path = rich_editor_tests.html; sourceTree = ""; }; + 3993FDE4880FB5D2EB58DC50BE4787B6 /* rich_editor_tests.html */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.html; path = rich_editor_tests.html; sourceTree = ""; }; 3ACC8280619FB2E73C87F0B3F67E248D /* outdent@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "outdent@2x.png"; sourceTree = ""; }; 3AF608CEFF69CDDB2B2B83D7AD24AD02 /* h3@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "h3@2x.png"; sourceTree = ""; }; 3BF184D91CE4439CD170887DBAD8B19E /* strikethrough@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "strikethrough@2x.png"; sourceTree = ""; }; 40634E726AC7B34435A3E907D32A5C7C /* justify_left.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = justify_left.png; sourceTree = ""; }; - 419B9639E6CB1C06F7323825651821DB /* RichEditorView.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; path = RichEditorView.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 419B9639E6CB1C06F7323825651821DB /* RichEditorView.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; path = RichEditorView.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 42AC2AC2794FF8534B679722C65B1912 /* h1.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = h1.png; sourceTree = ""; }; 46D119FA78DC9819A8493032125B2620 /* bg_color@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "bg_color@2x.png"; sourceTree = ""; }; 4705421B11136284C5A2B87EC1E402D8 /* text_color.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = text_color.png; sourceTree = ""; }; 4B2D2A1D90EF5849022855FEE8A8621A /* Pods-RichEditorViewSample-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-RichEditorViewSample-frameworks.sh"; sourceTree = ""; }; - 4C10094719178C91E5D2BD8A5D180278 /* RichEditorView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = RichEditorView.framework; path = RichEditorView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4C10094719178C91E5D2BD8A5D180278 /* RichEditorView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RichEditorView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4CA5823CF1F98505BAA502C0F0EC7A3F /* RichEditorView-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RichEditorView-umbrella.h"; sourceTree = ""; }; 4FAB2A52EE2F0E0BBBFA7406F553B118 /* insert_link.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = insert_link.png; sourceTree = ""; }; 515F0F4756781F63F55AE020958C4794 /* indent.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = indent.png; sourceTree = ""; }; - 5173100E3FA02EC57BB17823570CB919 /* assert.js */ = {isa = PBXFileReference; includeInIndex = 1; path = assert.js; sourceTree = ""; }; + 5173100E3FA02EC57BB17823570CB919 /* assert.js */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.javascript; path = assert.js; sourceTree = ""; }; 536CDBB92007CFBDD3DE6868BDB5D03A /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 554A4B603C8781B36AAA41AE77E96157 /* text_color@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "text_color@2x.png"; sourceTree = ""; }; 5B91B260954B0651B1C26524BE2D697A /* unordered_list@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "unordered_list@2x.png"; sourceTree = ""; }; 5DFB206650FFC90AD447DAF8FEB2742F /* CJWWebView+HackishAccessoryHiding.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "CJWWebView+HackishAccessoryHiding.m"; path = "RichEditorView/Classes/CJWWebView+HackishAccessoryHiding.m"; sourceTree = ""; }; - 629E9EEEE600BB5825323D84B709E4FF /* rich_editor.html */ = {isa = PBXFileReference; includeInIndex = 1; path = rich_editor.html; sourceTree = ""; }; + 629E9EEEE600BB5825323D84B709E4FF /* rich_editor.html */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.html; path = rich_editor.html; sourceTree = ""; }; 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - 686B40BF75D0E1CFDADF3D4D84AB5892 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; - 6B61B4ABF1BA88C9BDABDC55D7E551BE /* RichEditorView.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = RichEditorView.modulemap; sourceTree = ""; }; + 686B40BF75D0E1CFDADF3D4D84AB5892 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 6B61B4ABF1BA88C9BDABDC55D7E551BE /* RichEditorView.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = RichEditorView.modulemap; sourceTree = ""; }; 6D81F324079095F171731AB4619797C4 /* undo.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = undo.png; sourceTree = ""; }; 6FFE7C4D4983961147F0E4C624C72368 /* String+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+Extensions.swift"; path = "RichEditorView/Classes/String+Extensions.swift"; sourceTree = ""; }; 74F47A5FAB8778B6C4B3A763A3301FAB /* justify_right.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = justify_right.png; sourceTree = ""; }; @@ -146,7 +148,7 @@ 87B78775333844D7D0B5FE38CD5269DD /* ordered_list@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "ordered_list@2x.png"; sourceTree = ""; }; 8E5201FC0A8A8E25890C857A62C1369E /* outdent.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = outdent.png; sourceTree = ""; }; 93287F33CC93CB4BE2EB94A7E6932D56 /* redo.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = redo.png; sourceTree = ""; }; - 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 955E5EF5FD279F7BCFD6E49D33A43B13 /* insert_image@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "insert_image@2x.png"; sourceTree = ""; }; 995149FB6B72ECB416BE5699B20CAD36 /* h6.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = h6.png; sourceTree = ""; }; 9E681DA7B75D7C0A936638D8F75BDC37 /* UIView+Responder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIView+Responder.swift"; path = "RichEditorView/Classes/UIView+Responder.swift"; sourceTree = ""; }; @@ -155,7 +157,7 @@ A757C69F15DD4B02FA8EF9EA232E8644 /* justify_right@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "justify_right@2x.png"; sourceTree = ""; }; A7C3EE60A3DAE6F3EB94CC81FC9A4710 /* bg_color.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = bg_color.png; sourceTree = ""; }; B2B80B884BB03C1709A2B5498701ADD7 /* redo@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "redo@2x.png"; sourceTree = ""; }; - B5FF9C2F1AE59612324DEA5935B8E844 /* normalize.css */ = {isa = PBXFileReference; includeInIndex = 1; path = normalize.css; sourceTree = ""; }; + B5FF9C2F1AE59612324DEA5935B8E844 /* normalize.css */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.css; path = normalize.css; sourceTree = ""; }; BD6FBF94D08E72D14B52F5A429994D47 /* RichEditorToolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RichEditorToolbar.swift; path = RichEditorView/Classes/RichEditorToolbar.swift; sourceTree = ""; }; BDE33F3869E32C3D913A87BDAE1606B3 /* h4.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = h4.png; sourceTree = ""; }; BF23AAF0BD707F5833622FC2E6C06946 /* clear.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = clear.png; sourceTree = ""; }; @@ -176,7 +178,7 @@ DA6DC5F6F8EB9F2139B21E897A470ADF /* superscript@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "superscript@2x.png"; sourceTree = ""; }; E0EDDC438D2020C7BA232009A4DE5F89 /* h2@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "h2@2x.png"; sourceTree = ""; }; EA16B1A810146EDC0FD9026B032888C6 /* underline.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = underline.png; sourceTree = ""; }; - EAEC7B3111131D761C388ECDE17A3CA2 /* rich_editor_tests.js */ = {isa = PBXFileReference; includeInIndex = 1; path = rich_editor_tests.js; sourceTree = ""; }; + EAEC7B3111131D761C388ECDE17A3CA2 /* rich_editor_tests.js */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.javascript; path = rich_editor_tests.js; sourceTree = ""; }; EC1C3CF366594D395B8AE0F107A12568 /* Pods-RichEditorViewSample-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-RichEditorViewSample-resources.sh"; sourceTree = ""; }; EC28867585B491A0FBE918D7F86B9855 /* h2.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = h2.png; sourceTree = ""; }; F4BB9390B474F19BB030F4C224EF33D5 /* ordered_list.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = ordered_list.png; sourceTree = ""; }; @@ -264,6 +266,7 @@ BF78D179ADB074082DF857C918292309 /* bold@2x.png */, BF23AAF0BD707F5833622FC2E6C06946 /* clear.png */, 7BC1E3FE388C55D6509283638E10D069 /* clear@2x.png */, + 28BE08CE26CD4C06009FEF24 /* done.png */, 42AC2AC2794FF8534B679722C65B1912 /* h1.png */, 75638F6443B82B3A0F3E0BAB9CC8E688 /* h1@2x.png */, EC28867585B491A0FBE918D7F86B9855 /* h2.png */, @@ -475,6 +478,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = 7DB346D0F39D3F0E887471402A8071AB; @@ -534,6 +538,7 @@ 25DFDF691800BC06F20FF136543CB05A /* redo.png in Resources */, A1EA18F5DC7B107AE08FA270728CC517 /* redo@2x.png in Resources */, DD5BAAD83FD27A800F01D0C3EC2B3183 /* rich_editor.html in Resources */, + 28BE08CF26CD4C06009FEF24 /* done.png in Resources */, 775E624D321CDFD291D5914104748032 /* rich_editor.js in Resources */, 101E4D87E21C11A3C4CA0DF411276E86 /* rich_editor_tests.html in Resources */, B626C79E2F15F8E4D52DAB0DAE0F26CB /* rich_editor_tests.js in Resources */, diff --git a/RichEditorViewSample/RichEditorViewSample/ViewController.swift b/RichEditorViewSample/RichEditorViewSample/ViewController.swift index d552c691..2926c8ef 100644 --- a/RichEditorViewSample/RichEditorViewSample/ViewController.swift +++ b/RichEditorViewSample/RichEditorViewSample/ViewController.swift @@ -29,15 +29,6 @@ class ViewController: UIViewController { toolbar.delegate = self toolbar.editor = editorView - - // We will create a custom action that clears all the input text when it is pressed - let item = RichEditorOptionItem(image: nil, title: "Clear") { toolbar in - toolbar.editor?.html = "" - } - - var options = toolbar.options - options.append(item) - toolbar.options = options } } @@ -55,7 +46,7 @@ extension ViewController: RichEditorDelegate { } extension ViewController: RichEditorToolbarDelegate { - + fileprivate func randomColor() -> UIColor { let colors: [UIColor] = [ .red, @@ -86,8 +77,18 @@ extension ViewController: RichEditorToolbarDelegate { func richEditorToolbarInsertLink(_ toolbar: RichEditorToolbar) { // Can only add links to selected text, so make sure there is a range selection first - if toolbar.editor?.hasRangeSelection == true { - toolbar.editor?.insertLink("http://github.com/cjwirth/RichEditorView", title: "Github Link") + toolbar.editor?.backupElement() + if toolbar.editor?.hasRangeSelection == true, let link = toolbar.searchBar.text { + toolbar.editor?.insertLink(link, title: "") } + toolbar.resetBars() } + + func richEditorTookFocus(_ editor: RichEditorView) { + // reset + guard let iav = editor.inputAccessoryView as? RichEditorToolbar else { return } + iav.resetBars() + } + + } From 232680bb3fee384903f9f714a0b6b87aa5a75791 Mon Sep 17 00:00:00 2001 From: Engin Date: Wed, 18 Aug 2021 17:45:08 +0300 Subject: [PATCH 09/11] adde missing icons --- .../Pods/Pods.xcodeproj/project.pbxproj | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/RichEditorViewSample/Pods/Pods.xcodeproj/project.pbxproj b/RichEditorViewSample/Pods/Pods.xcodeproj/project.pbxproj index 06829d6d..8d1efddd 100644 --- a/RichEditorViewSample/Pods/Pods.xcodeproj/project.pbxproj +++ b/RichEditorViewSample/Pods/Pods.xcodeproj/project.pbxproj @@ -19,6 +19,12 @@ 21A9B7FCC0D608BD65DE2AAEB9E2BD28 /* bg_color@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 46D119FA78DC9819A8493032125B2620 /* bg_color@2x.png */; }; 25DFDF691800BC06F20FF136543CB05A /* redo.png in Resources */ = {isa = PBXBuildFile; fileRef = 93287F33CC93CB4BE2EB94A7E6932D56 /* redo.png */; }; 26B674B1D5DD424360E1B6AB350F9840 /* style.css in Resources */ = {isa = PBXBuildFile; fileRef = 1672230420C54446C8D87D1F2A4C31DC /* style.css */; }; + 2844ED6026CD52CD00F88027 /* blockQuote.png in Resources */ = {isa = PBXBuildFile; fileRef = 2844ED5F26CD52CD00F88027 /* blockQuote.png */; }; + 2844ED6226CD52EC00F88027 /* size.png in Resources */ = {isa = PBXBuildFile; fileRef = 2844ED6126CD52EB00F88027 /* size.png */; }; + 2844ED6426CD532800F88027 /* f.png in Resources */ = {isa = PBXBuildFile; fileRef = 2844ED6326CD532800F88027 /* f.png */; }; + 2844ED6726CD53F000F88027 /* code.png in Resources */ = {isa = PBXBuildFile; fileRef = 2844ED6526CD53EF00F88027 /* code.png */; }; + 2844ED6826CD53F000F88027 /* justify.png in Resources */ = {isa = PBXBuildFile; fileRef = 2844ED6626CD53EF00F88027 /* justify.png */; }; + 2844ED6A26CD544000F88027 /* back.png in Resources */ = {isa = PBXBuildFile; fileRef = 2844ED6926CD544000F88027 /* back.png */; }; 28BE08CF26CD4C06009FEF24 /* done.png in Resources */ = {isa = PBXBuildFile; fileRef = 28BE08CE26CD4C06009FEF24 /* done.png */; }; 2CE9FEA70AB67B34F2CFF606AAFC3C40 /* justify_left.png in Resources */ = {isa = PBXBuildFile; fileRef = 40634E726AC7B34435A3E907D32A5C7C /* justify_left.png */; }; 339A87EF9A671044103479E863C9BCA4 /* Pods-RichEditorViewSample-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 7980878382C0AB691C47F03DA0538E4D /* Pods-RichEditorViewSample-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -106,6 +112,12 @@ 1DA527F8D0CC821E2D123B407B290476 /* undo@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "undo@2x.png"; sourceTree = ""; }; 25514417F0E67AC446ADC1943AD650BB /* RichEditorView.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RichEditorView.xcconfig; sourceTree = ""; }; 25A38A9BA9BDB52FC3E88D49A58C33B3 /* rich_editor.js */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.javascript; path = rich_editor.js; sourceTree = ""; }; + 2844ED5F26CD52CD00F88027 /* blockQuote.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = blockQuote.png; path = ../../../../icons/blockQuote.png; sourceTree = ""; }; + 2844ED6126CD52EB00F88027 /* size.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = size.png; path = ../../../../icons/size.png; sourceTree = ""; }; + 2844ED6326CD532800F88027 /* f.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = f.png; path = ../../../../icons/f.png; sourceTree = ""; }; + 2844ED6526CD53EF00F88027 /* code.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = code.png; path = ../../../../code.png; sourceTree = ""; }; + 2844ED6626CD53EF00F88027 /* justify.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = justify.png; path = ../../../../justify.png; sourceTree = ""; }; + 2844ED6926CD544000F88027 /* back.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = back.png; path = ../../../../../Downloads/back.png; sourceTree = ""; }; 28BE08CE26CD4C06009FEF24 /* done.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = done.png; sourceTree = ""; }; 2EDAE0C8992041C9DF22B7387230C7D5 /* strikethrough.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = strikethrough.png; sourceTree = ""; }; 34C2463E7C6EEC1D53284EFE2030A449 /* justify_center@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "justify_center@2x.png"; sourceTree = ""; }; @@ -262,11 +274,17 @@ children = ( A7C3EE60A3DAE6F3EB94CC81FC9A4710 /* bg_color.png */, 46D119FA78DC9819A8493032125B2620 /* bg_color@2x.png */, + 2844ED6926CD544000F88027 /* back.png */, + 2844ED6126CD52EB00F88027 /* size.png */, + 2844ED5F26CD52CD00F88027 /* blockQuote.png */, 047AADD0F93334158F1D9DF4A65F1690 /* bold.png */, BF78D179ADB074082DF857C918292309 /* bold@2x.png */, + 2844ED6526CD53EF00F88027 /* code.png */, + 2844ED6626CD53EF00F88027 /* justify.png */, BF23AAF0BD707F5833622FC2E6C06946 /* clear.png */, 7BC1E3FE388C55D6509283638E10D069 /* clear@2x.png */, 28BE08CE26CD4C06009FEF24 /* done.png */, + 2844ED6326CD532800F88027 /* f.png */, 42AC2AC2794FF8534B679722C65B1912 /* h1.png */, 75638F6443B82B3A0F3E0BAB9CC8E688 /* h1@2x.png */, EC28867585B491A0FBE918D7F86B9855 /* h2.png */, @@ -500,6 +518,7 @@ 980EC911ED9BF2854E4D5ED9B1553BC3 /* assert.js in Resources */, 6D1AC8F228C3FC32A4F0509711D06AF9 /* bg_color.png in Resources */, 21A9B7FCC0D608BD65DE2AAEB9E2BD28 /* bg_color@2x.png in Resources */, + 2844ED6026CD52CD00F88027 /* blockQuote.png in Resources */, 1AE3AAF000BBFDDFE55115E2C5E80439 /* bold.png in Resources */, 6F09B9ECDD98EFDE9E6DDCD1408EB1AA /* bold@2x.png in Resources */, D58C033AC7594A3E1370C49A3B592B93 /* clear.png in Resources */, @@ -518,6 +537,7 @@ 73A1CF56D0367C806DCD7BD2FF8A6D0B /* h6@2x.png in Resources */, C09DCE45D5C9C32B460098AA306B22D2 /* indent.png in Resources */, 7A62BFAF8C00A61A1428D72F900174F2 /* indent@2x.png in Resources */, + 2844ED6726CD53F000F88027 /* code.png in Resources */, 55B484334043AA0164859119C677AE00 /* insert_image.png in Resources */, 6EFC51A4D131CB5F4A5530F4CB3E8B38 /* insert_image@2x.png in Resources */, 34A1ABB01305D4836C844873604620BD /* insert_link.png in Resources */, @@ -530,10 +550,12 @@ BF5DFF63A0A96BB23396EF1E4EBABADA /* justify_left@2x.png in Resources */, D97D9143E23A43F69806AE54C7C61A00 /* justify_right.png in Resources */, 7E3871C827CE583D825B4D5682EB8865 /* justify_right@2x.png in Resources */, + 2844ED6226CD52EC00F88027 /* size.png in Resources */, DE091E264C84B2AB1C74D48BCC9C7A3A /* normalize.css in Resources */, 52899C92D83CCCA95FFDA7C0AD3A680F /* ordered_list.png in Resources */, EAFD26C8E13400DC1B3674FE75983316 /* ordered_list@2x.png in Resources */, 8A7CB5AC6BCE2426BF2427464F40FC4B /* outdent.png in Resources */, + 2844ED6426CD532800F88027 /* f.png in Resources */, E9CDDB959B01621DF0930AC7895B532F /* outdent@2x.png in Resources */, 25DFDF691800BC06F20FF136543CB05A /* redo.png in Resources */, A1EA18F5DC7B107AE08FA270728CC517 /* redo@2x.png in Resources */, @@ -541,6 +563,7 @@ 28BE08CF26CD4C06009FEF24 /* done.png in Resources */, 775E624D321CDFD291D5914104748032 /* rich_editor.js in Resources */, 101E4D87E21C11A3C4CA0DF411276E86 /* rich_editor_tests.html in Resources */, + 2844ED6826CD53F000F88027 /* justify.png in Resources */, B626C79E2F15F8E4D52DAB0DAE0F26CB /* rich_editor_tests.js in Resources */, C076BB36B4F4F037B85747BE9D87EAF9 /* strikethrough.png in Resources */, 74A4F8EBFDC3DA45C916A0DE9A4D974A /* strikethrough@2x.png in Resources */, @@ -554,6 +577,7 @@ 585DEF9467CFA72C7E404F7D0A89904C /* underline.png in Resources */, C6AE35467D92959BD10CE2FB6F1604E0 /* underline@2x.png in Resources */, DB08B964EEBB1277EC9F0C0E4478EFBA /* undo.png in Resources */, + 2844ED6A26CD544000F88027 /* back.png in Resources */, 80BEC46A2037D67ED588499253C4FF50 /* undo@2x.png in Resources */, 81D5B40378CC56BF877935C94E3432A6 /* unordered_list.png in Resources */, 73F2A3F6B2F47AE45D961A1577180675 /* unordered_list@2x.png in Resources */, From 0edeaf1a75cac434df1751970b634b4d3b30a77b Mon Sep 17 00:00:00 2001 From: Engin Date: Wed, 18 Aug 2021 17:51:35 +0300 Subject: [PATCH 10/11] added link option --- .../Classes/RichEditorOptionItem.swift | 7 ++++-- .../Classes/RichEditorToolbar.swift | 23 +++++++++++++------ .../RichEditorViewSample/ViewController.swift | 9 +------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/RichEditorView/Classes/RichEditorOptionItem.swift b/RichEditorView/Classes/RichEditorOptionItem.swift index f2cdc995..38e2660d 100644 --- a/RichEditorView/Classes/RichEditorOptionItem.swift +++ b/RichEditorView/Classes/RichEditorOptionItem.swift @@ -241,6 +241,7 @@ public enum RichEditorDefaultOption: RichEditorOption { case allignment case image case link + case pasteLink public static let all: [RichEditorDefaultOption] = [ .clear, .undo, .redo, .bold, .italic, .header, .size, .font, @@ -268,7 +269,7 @@ public enum RichEditorDefaultOption: RichEditorOption { case .textColor: name = "text_color" case .textBackgroundColor: name = "bg_color" case .header: name = "h" - + case .pasteLink: name = "done" case .image: name = "insert_image" case .link: name = "insert_link" case .size: name = "size" @@ -299,6 +300,7 @@ public enum RichEditorDefaultOption: RichEditorOption { case .allignment: return NSLocalizedString("Allignment", comment: "") case .image: return NSLocalizedString("Image", comment: "") case .link: return NSLocalizedString("Link", comment: "") + case .pasteLink: return NSLocalizedString("Link", comment: "") case .size: return NSLocalizedString("Size", comment: "") case .font: return NSLocalizedString("Font", comment: "") } @@ -321,7 +323,8 @@ public enum RichEditorDefaultOption: RichEditorOption { case .header: toolbar.editor?.showHeader() case .allignment: toolbar.editor?.showAllignments() case .image: toolbar.delegate?.richEditorToolbarInsertImage?(toolbar) - case .link: toolbar.delegate?.richEditorToolbarInsertLink?(toolbar) + case .link: toolbar.editor?.showLink() + case .pasteLink: toolbar.delegate?.richEditorToolbarInsertLink?(toolbar) case .size: toolbar.editor?.showTextSize() case .font: toolbar.editor?.showFonts() case .blockquote: toolbar.editor?.blockquote() diff --git a/RichEditorView/Classes/RichEditorToolbar.swift b/RichEditorView/Classes/RichEditorToolbar.swift index 3f667b95..436acfd0 100644 --- a/RichEditorView/Classes/RichEditorToolbar.swift +++ b/RichEditorView/Classes/RichEditorToolbar.swift @@ -48,7 +48,7 @@ import UIKit } /// RichEditorToolbar is UIView that contains the toolbar for actions that can be performed on a RichEditorView -@objcMembers open class RichEditorToolbar: UIView, UISearchBarDelegate { +@objcMembers open class RichEditorToolbar: UIView { /// The delegate to receive events that cannot be automatically completed open weak var delegate: RichEditorToolbarDelegate? @@ -87,20 +87,29 @@ import UIKit bar.isHidden = true bar.alpha = 0 - // We will create a custom action that clears all the input text when it is pressed - let button = RichEditorOptionItem(image: nil, title: "Clear") { toolbar in - toolbar.editor?.html = "" + let option = RichEditorDefaultOption.pasteLink + let button: RichBarButtonItem + + let handler = { [weak self] in + if let strongSelf = self { + option.action(strongSelf) + } + } + if let image = option.image { + button = RichBarButtonItem(image: image, handler: handler) + } else { + let title = option.title + button = RichBarButtonItem(title: title, handler: handler) } - + let negativeSeperator = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) negativeSeperator.width = 12 - searchBar.delegate = self searchBar.frame = CGRect(x: 0, y:0, width: bounds.width - 70, height: 44) searchBar.barTintColor = .lightGray searchBar.setImage(UIImage(), for: .search, state: .normal) searchBar.placeholder = "paste a link e.g., https://www.wikipedia.org" let searchBarButton = UIBarButtonItem.init(customView: searchBar) - bar.items = [searchBarButton,negativeSeperator] + bar.items = [searchBarButton,negativeSeperator,button] toolbarScroll.addSubview(bar) return bar }() diff --git a/RichEditorViewSample/RichEditorViewSample/ViewController.swift b/RichEditorViewSample/RichEditorViewSample/ViewController.swift index 2926c8ef..e74c0ae9 100644 --- a/RichEditorViewSample/RichEditorViewSample/ViewController.swift +++ b/RichEditorViewSample/RichEditorViewSample/ViewController.swift @@ -76,19 +76,12 @@ extension ViewController: RichEditorToolbarDelegate { } func richEditorToolbarInsertLink(_ toolbar: RichEditorToolbar) { - // Can only add links to selected text, so make sure there is a range selection first toolbar.editor?.backupElement() - if toolbar.editor?.hasRangeSelection == true, let link = toolbar.searchBar.text { + if let link = toolbar.searchBar.text { toolbar.editor?.insertLink(link, title: "") } toolbar.resetBars() } - func richEditorTookFocus(_ editor: RichEditorView) { - // reset - guard let iav = editor.inputAccessoryView as? RichEditorToolbar else { return } - iav.resetBars() - } - } From 2ad24dac1d5d6736bdef2b6b2c77dac3270b27be Mon Sep 17 00:00:00 2001 From: Engin Date: Wed, 18 Aug 2021 18:02:23 +0300 Subject: [PATCH 11/11] animation removed --- RichEditorView/Classes/RichEditorToolbar.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/RichEditorView/Classes/RichEditorToolbar.swift b/RichEditorView/Classes/RichEditorToolbar.swift index 436acfd0..c69b2999 100644 --- a/RichEditorView/Classes/RichEditorToolbar.swift +++ b/RichEditorView/Classes/RichEditorToolbar.swift @@ -183,8 +183,8 @@ import UIKit } func toggleBars(bar: UIToolbar) { - UIView.animate(withDuration: 0.5) { [self] in - if bar.isHidden { + toolbarScroll.setContentOffset(.zero, animated: true) + if bar.isHidden { bar.alpha = 1 toolbarScroll.contentSize.width = bar.bounds.size.width } else { @@ -194,8 +194,6 @@ import UIKit } bar.isHidden = !bar.isHidden defautToolbar.isHidden = !bar.isHidden - toolbarScroll.setContentOffset(.zero, animated: true) - } } public override init(frame: CGRect) {