├── ZSSRichTextEditor ├── en.lproj │ └── InfoPlist.strings ├── 120.png ├── 152.png ├── 76.png ├── Icon@2x.png ├── Images.xcassets │ ├── Contents.json │ └── AppIcon.appiconset │ │ ├── icon.png │ │ ├── Icon-76.png │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ ├── Icon-76@2x.png │ │ ├── Icon-Small.png │ │ ├── Icon-83.5@2x.png │ │ ├── Icon-Small-40.png │ │ ├── Icon-Small@2x.png │ │ ├── Icon-Small@3x.png │ │ ├── Icon-Notification.png │ │ ├── Icon-Small-40@2x.png │ │ ├── Icon-Small-40@3x.png │ │ ├── Icon-Notification@2x.png │ │ ├── Icon-Notification@3x.png │ │ └── Contents.json ├── Default-568h@2x.png ├── Source │ ├── Images │ │ ├── ZSSh1.png │ │ ├── ZSSh2.png │ │ ├── ZSSh3.png │ │ ├── ZSSh4.png │ │ ├── ZSSh5.png │ │ ├── ZSSh6.png │ │ ├── ZSSbold.png │ │ ├── ZSSfonts.png │ │ ├── ZSSh1@2x.png │ │ ├── ZSSh2@2x.png │ │ ├── ZSSh3@2x.png │ │ ├── ZSSh4@2x.png │ │ ├── ZSSh5@2x.png │ │ ├── ZSSh6@2x.png │ │ ├── ZSSimage.png │ │ ├── ZSSindent.png │ │ ├── ZSSitalic.png │ │ ├── ZSSlink.png │ │ ├── ZSSpicker.png │ │ ├── ZSSredo.png │ │ ├── ZSStable.png │ │ ├── ZSSundo.png │ │ ├── ZSSunlink.png │ │ ├── ZSSbgcolor.png │ │ ├── ZSSbold@2x.png │ │ ├── ZSSfonts@2x.png │ │ ├── ZSSimage@2x.png │ │ ├── ZSSkeyboard.png │ │ ├── ZSSlink@2x.png │ │ ├── ZSSoutdent.png │ │ ├── ZSSredo@2x.png │ │ ├── ZSStable@2x.png │ │ ├── ZSSundo@2x.png │ │ ├── ZSSbgcolor@2x.png │ │ ├── ZSSclearstyle.png │ │ ├── ZSSimageDevice.png │ │ ├── ZSSindent@2x.png │ │ ├── ZSSitalic@2x.png │ │ ├── ZSSkeyboard@2x.png │ │ ├── ZSSleftjustify.png │ │ ├── ZSSorderedlist.png │ │ ├── ZSSoutdent@2x.png │ │ ├── ZSSparagraph.png │ │ ├── ZSSpicker@2x.png │ │ ├── ZSSquicklink.png │ │ ├── ZSSsubscript.png │ │ ├── ZSSsuperscript.png │ │ ├── ZSStextcolor.png │ │ ├── ZSSunderline.png │ │ ├── ZSSunlink@2x.png │ │ ├── ZSSviewsource.png │ │ ├── ZSScenterjustify.png │ │ ├── ZSSclearstyle@2x.png │ │ ├── ZSSforcejustify.png │ │ ├── ZSSinsertkeyword.png │ │ ├── ZSSparagraph@2x.png │ │ ├── ZSSquicklink@2x.png │ │ ├── ZSSrightjustify.png │ │ ├── ZSSstrikethrough.png │ │ ├── ZSSsubscript@2x.png │ │ ├── ZSStextcolor@2x.png │ │ ├── ZSSunderline@2x.png │ │ ├── ZSSunorderedlist.png │ │ ├── ZSSviewsource@2x.png │ │ ├── ZSScenterjustify@2x.png │ │ ├── ZSSforcejustify@2x.png │ │ ├── ZSShorizontalrule.png │ │ ├── ZSSimageDevice@2x.png │ │ ├── ZSSinsertkeyword@2x.png │ │ ├── ZSSleftjustify@2x.png │ │ ├── ZSSorderedlist@2x.png │ │ ├── ZSSrightjustify@2x.png │ │ ├── ZSSstrikethrough@2x.png │ │ ├── ZSSsuperscript@2x.png │ │ ├── ZSSunorderedlist@2x.png │ │ └── ZSShorizontalrule@2x.png │ ├── ZSSBarButtonItem.m │ ├── ZSSBarButtonItem.h │ ├── ZSSTextView.h │ ├── ZSSFontsViewController.h │ ├── Third Party │ │ ├── HRBrightnessCursor.h │ │ ├── HRColorPickerMacros.h │ │ ├── HRCgUtil.h │ │ ├── CYRTextStorage.h │ │ ├── HRColorCursor.h │ │ ├── CYRToken.h │ │ ├── CYRToken.m │ │ ├── CYRLayoutManager.h │ │ ├── CYRTextView.h │ │ ├── HRColorUtil.h │ │ ├── HRColorPickerViewController.h │ │ ├── HRColorCursor.m │ │ ├── HRCgUtil.m │ │ ├── HRBrightnessCursor.m │ │ ├── HRColorPickerView.h │ │ ├── HRColorUtil.m │ │ ├── HRColorPickerViewController.m │ │ ├── CYRTextStorage.m │ │ ├── CYRLayoutManager.m │ │ ├── CYRTextView.m │ │ └── HRColorPickerView.m │ ├── editor.html │ ├── ZSSFontsViewController.m │ ├── ZSSTextView.m │ └── ZSSRichTextEditor.h ├── Classes │ ├── ZSSDemoList.h │ ├── ZSSColorViewController.h │ ├── ZSSLargeViewController.h │ ├── ZSSSelectiveViewController.h │ ├── ZSSPlaceholderViewController.h │ ├── ZSSCustomButtonsViewController.h │ ├── ZSSDemoViewController.h │ ├── ZSSAppDelegate.h │ ├── ZSSDemoPickerViewController.h │ ├── ZSSPlaceholderViewController.m │ ├── ZSSSelectiveViewController.m │ ├── ZSSColorViewController.m │ ├── ZSSCustomButtonsViewController.m │ ├── ZSSDemoPickerViewController.m │ ├── ZSSAppDelegate.m │ ├── ZSSDemoViewController.m │ ├── ZSSLargeViewController.m │ └── ZSSDemoList.m ├── DemoModalViewController.h ├── ZSSRichTextEditor-Prefix.pch ├── main.m ├── DemoModalViewController.m ├── ZSSRichTextEditor-Info.plist └── Launch Screen.storyboard ├── ZSSRichTextEditor.xcodeproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ ├── ZSSRichTextEditor.xcscmblueprint │ └── ZSSRichTextEditor.xccheckout ├── LICENSE.txt ├── ZSSRichTextEditor.podspec ├── .gitignore └── README.md /ZSSRichTextEditor/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/120.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/152.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/76.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Icon@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ZSSRichTextEditor/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Default-568h@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSh1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSh1.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSh2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSh2.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSh3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSh3.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSh4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSh4.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSh5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSh5.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSh6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSh6.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSbold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSbold.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSfonts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSfonts.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSh1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSh1@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSh2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSh2@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSh3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSh3@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSh4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSh4@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSh5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSh5@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSh6@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSh6@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSimage.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSindent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSindent.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSitalic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSitalic.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSlink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSlink.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSpicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSpicker.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSredo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSredo.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSStable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSStable.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSundo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSundo.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSunlink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSunlink.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSbgcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSbgcolor.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSbold@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSbold@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSfonts@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSfonts@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSimage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSimage@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSkeyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSkeyboard.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSlink@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSlink@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSoutdent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSoutdent.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSredo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSredo@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSStable@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSStable@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSundo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSundo@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSbgcolor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSbgcolor@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSclearstyle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSclearstyle.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSimageDevice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSimageDevice.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSindent@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSindent@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSitalic@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSitalic@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSkeyboard@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSkeyboard@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSleftjustify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSleftjustify.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSorderedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSorderedlist.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSoutdent@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSoutdent@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSparagraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSparagraph.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSpicker@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSpicker@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSquicklink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSquicklink.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSsubscript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSsubscript.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSsuperscript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSsuperscript.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSStextcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSStextcolor.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSunderline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSunderline.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSunlink@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSunlink@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSviewsource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSviewsource.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSScenterjustify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSScenterjustify.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSclearstyle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSclearstyle@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSforcejustify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSforcejustify.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSinsertkeyword.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSinsertkeyword.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSparagraph@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSparagraph@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSquicklink@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSquicklink@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSrightjustify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSrightjustify.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSstrikethrough.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSstrikethrough.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSsubscript@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSsubscript@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSStextcolor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSStextcolor@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSunderline@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSunderline@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSunorderedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSunorderedlist.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSviewsource@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSviewsource@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSScenterjustify@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSScenterjustify@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSforcejustify@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSforcejustify@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSShorizontalrule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSShorizontalrule.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSimageDevice@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSimageDevice@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSinsertkeyword@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSinsertkeyword@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSleftjustify@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSleftjustify@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSorderedlist@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSorderedlist@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSrightjustify@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSrightjustify@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSstrikethrough@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSstrikethrough@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSsuperscript@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSsuperscript@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSSunorderedlist@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSSunorderedlist@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Images/ZSShorizontalrule@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Source/Images/ZSShorizontalrule@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/icon.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Small-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Small-40.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Notification.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Notification@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Notification@2x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Notification@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnhubbard/ZSSRichTextEditor/HEAD/ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Icon-Notification@3x.png -------------------------------------------------------------------------------- /ZSSRichTextEditor.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSDemoList.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSDemoList.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 8/12/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZSSDemoList : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/ZSSBarButtonItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSBarButtonItem.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 12/3/13. 6 | // Copyright (c) 2013 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSBarButtonItem.h" 10 | 11 | @implementation ZSSBarButtonItem 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZSSRichTextEditor.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/DemoModalViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DemoModalViewController.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Will Swan on 02/09/2016. 6 | // Copyright © 2016 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DemoModalViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSColorViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSColorViewController.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 8/12/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSRichTextEditor.h" 10 | 11 | @interface ZSSColorViewController : ZSSRichTextEditor 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSLargeViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSLargeViewController.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 8/13/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSRichTextEditor.h" 10 | 11 | @interface ZSSLargeViewController : ZSSRichTextEditor 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSSelectiveViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSSelectiveViewController.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 8/14/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSRichTextEditor.h" 10 | 11 | @interface ZSSSelectiveViewController : ZSSRichTextEditor 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSPlaceholderViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSPlaceholderViewController.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 8/14/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSRichTextEditor.h" 10 | 11 | @interface ZSSPlaceholderViewController : ZSSRichTextEditor 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSCustomButtonsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSCustomButtonsViewController.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 8/14/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSRichTextEditor.h" 10 | 11 | @interface ZSSCustomButtonsViewController : ZSSRichTextEditor 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSDemoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSDemoViewController.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 11/29/13. 6 | // Copyright (c) 2013 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ZSSRichTextEditor.h" 11 | 12 | @interface ZSSDemoViewController : ZSSRichTextEditor 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/ZSSBarButtonItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSBarButtonItem.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 12/3/13. 6 | // Copyright (c) 2013 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZSSBarButtonItem : UIBarButtonItem 12 | 13 | @property (nonatomic, strong) NSString *label; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/ZSSRichTextEditor-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 11/28/13. 6 | // Copyright (c) 2013 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "ZSSAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([ZSSAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/ZSSTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSTextView.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 1/29/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "CYRTextView.h" 10 | 11 | @interface ZSSTextView : CYRTextView 12 | 13 | @property (nonatomic, strong) UIFont *defaultFont; 14 | @property (nonatomic, strong) UIFont *boldFont; 15 | @property (nonatomic, strong) UIFont *italicFont; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSAppDelegate.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 11/28/13. 6 | // Copyright (c) 2013 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ZSSDemoList.h" 11 | 12 | @interface ZSSAppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | @property (nonatomic, strong) ZSSDemoList *mainViewController; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSDemoPickerViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSDemoPickerViewController.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 1/30/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ZSSDemoViewController.h" 11 | 12 | @interface ZSSDemoPickerViewController : UIViewController 13 | 14 | @property (nonatomic, strong) ZSSDemoViewController *demoView; 15 | @property (nonatomic) BOOL isInsertImagePicker; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSPlaceholderViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSPlaceholderViewController.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 8/14/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSPlaceholderViewController.h" 10 | 11 | @interface ZSSPlaceholderViewController () 12 | 13 | @end 14 | 15 | @implementation ZSSPlaceholderViewController 16 | 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | 22 | self.title = @"Placeholder"; 23 | 24 | self.placeholder = @"Please tap to start editing"; 25 | 26 | } 27 | 28 | - (void)didReceiveMemoryWarning 29 | { 30 | [super didReceiveMemoryWarning]; 31 | // Dispose of any resources that can be recreated. 32 | } 33 | 34 | 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSSelectiveViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSSelectiveViewController.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 8/14/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSSelectiveViewController.h" 10 | 11 | @interface ZSSSelectiveViewController () 12 | 13 | @end 14 | 15 | @implementation ZSSSelectiveViewController 16 | 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | 22 | self.title = @"Selective"; 23 | 24 | // HTML Content to set in the editor 25 | NSString *html = @"

Example showing just a few toolbar buttons.

"; 26 | 27 | // Choose which toolbar items to show 28 | self.enabledToolbarItems = @[ZSSRichTextEditorToolbarBold, ZSSRichTextEditorToolbarH1, ZSSRichTextEditorToolbarParagraph]; 29 | 30 | // Set the HTML contents of the editor 31 | [self setHTML:html]; 32 | 33 | 34 | } 35 | 36 | - (void)didReceiveMemoryWarning 37 | { 38 | [super didReceiveMemoryWarning]; 39 | // Dispose of any resources that can be recreated. 40 | } 41 | 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Zed Said Studio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/ZSSFontsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSFontsViewController.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Will Swan on 03/09/2016. 6 | // Copyright © 2016 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(int16_t, ZSSFontFamily) { 12 | 13 | ZSSFontFamilyDefault = 0, 14 | ZSSFontFamilyTrebuchet = 1, 15 | ZSSFontFamilyVerdana = 2, 16 | ZSSFontFamilyGeorgia = 3, 17 | ZSSFontFamilyPalatino = 4, 18 | ZSSFontFamilyTimesNew = 5, 19 | ZSSFontFamilyCourierNew = 6, 20 | 21 | 22 | }; 23 | 24 | @protocol ZSSFontsViewControllerDelegate 25 | - (void)setSelectedFontFamily:(ZSSFontFamily)fontFamily; 26 | @end 27 | 28 | @interface ZSSFontsViewController : UIViewController { 29 | 30 | id __weak delegate; 31 | 32 | ZSSFontFamily _font; 33 | 34 | } 35 | 36 | + (ZSSFontsViewController *)cancelableFontPickerViewControllerWithFontFamily:(ZSSFontFamily)fontFamily; 37 | 38 | - (id)initWithFontFamily:(ZSSFontFamily)fontFamily; 39 | 40 | @property (weak) id delegate; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/DemoModalViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DemoModalViewController.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Will Swan on 02/09/2016. 6 | // Copyright © 2016 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "DemoModalViewController.h" 10 | 11 | @interface DemoModalViewController () 12 | 13 | @end 14 | 15 | @implementation DemoModalViewController 16 | 17 | - (void)viewDidLoad { 18 | 19 | [super viewDidLoad]; 20 | 21 | //Back Button 22 | UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10.0f, 10.0f, 100.0f, 44.0f)]; 23 | [button setTitle:@"Back" forState:UIControlStateNormal]; 24 | [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 25 | [button addTarget:self action:@selector(dismiss) forControlEvents:UIControlEventTouchUpInside]; 26 | [self.view addSubview:button]; 27 | 28 | } 29 | 30 | - (void)dismiss { 31 | 32 | [self dismissViewControllerAnimated:NO completion:nil]; 33 | 34 | } 35 | 36 | - (void)didReceiveMemoryWarning { 37 | [super didReceiveMemoryWarning]; 38 | // Dispose of any resources that can be recreated. 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSColorViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSColorViewController.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 8/12/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSColorViewController.h" 10 | 11 | @interface ZSSColorViewController () 12 | 13 | @end 14 | 15 | @implementation ZSSColorViewController 16 | 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | 22 | self.title = @"Colors"; 23 | 24 | // HTML Content to set in the editor 25 | NSString *html = @"

This editor is using custom toolbar colors.

"; 26 | 27 | // Set the base URL if you would like to use relative links, such as to images. 28 | self.baseURL = [NSURL URLWithString:@"http://www.zedsaid.com"]; 29 | 30 | // Set the toolbar item color 31 | self.toolbarItemTintColor = [UIColor redColor]; 32 | 33 | // Set the toolbar selected color 34 | self.toolbarItemSelectedTintColor = [UIColor blackColor]; 35 | 36 | // Set the HTML contents of the editor 37 | [self setHTML:html]; 38 | 39 | } 40 | 41 | - (void)didReceiveMemoryWarning 42 | { 43 | [super didReceiveMemoryWarning]; 44 | // Dispose of any resources that can be recreated. 45 | } 46 | 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRBrightnessCursor.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2011 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #import 29 | 30 | @interface HRBrightnessCursor : UIView 31 | 32 | - (id)initWithPoint:(CGPoint)point; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRColorPickerMacros.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #ifndef HRColorPickerMacros_h 29 | #define HRColorPickerMacros_h 30 | 31 | #if !__has_feature(objc_arc_weak) 32 | #define weak unsafe_unretained 33 | #undef __weak 34 | #define __weak __unsafe_unretained 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRCgUtil.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2011 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #import "HRColorUtil.h" 29 | 30 | // 角丸のパスをセット 31 | void HRSetRoundedRectanglePath(CGContextRef context,const CGRect rect,CGFloat radius); 32 | // かっこいい角丸の四角を描きます。色付き。 33 | void HRDrawSquareColorBatch(CGContextRef context,CGPoint position,HRRGBColor* color,float size); -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/CYRTextStorage.h: -------------------------------------------------------------------------------- 1 | // 2 | // CYRTextStorage.h 3 | // 4 | // Version 0.2.0 5 | // 6 | // Created by Illya Busigin on 01/05/2014. 7 | // Copyright (c) 2014 Cyrillian, Inc. 8 | // 9 | // Distributed under MIT license. 10 | // Get the latest version from here: 11 | // 12 | // https://github.com/illyabusigin/CYRTextView 13 | // 14 | // The MIT License (MIT) 15 | // 16 | // Copyright (c) 2014 Cyrillian, Inc. 17 | // 18 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 19 | // this software and associated documentation files (the "Software"), to deal in 20 | // the Software without restriction, including without limitation the rights to 21 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 22 | // the Software, and to permit persons to whom the Software is furnished to do so, 23 | // subject to the following conditions: 24 | // 25 | // The above copyright notice and this permission notice shall be included in all 26 | // copies or substantial portions of the Software. 27 | // 28 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 30 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 31 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 32 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 33 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 34 | 35 | #import 36 | 37 | @interface CYRTextStorage : NSTextStorage 38 | 39 | @property (nonatomic, strong) NSArray *tokens; 40 | @property (nonatomic, strong) UIFont *defaultFont; 41 | 42 | - (void)update; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /ZSSRichTextEditor.xcodeproj/project.xcworkspace/xcshareddata/ZSSRichTextEditor.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "6C2C2B670C50C326F4CDE75C16826EDA0491AEF0", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "6C2C2B670C50C326F4CDE75C16826EDA0491AEF0" : 0, 8 | "D4901E2DECC4ACCA927A8E9BA33FBB59E4A0AF3D" : 0 9 | }, 10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "1D85276D-8013-471B-8035-FD0DD32B9643", 11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 12 | "6C2C2B670C50C326F4CDE75C16826EDA0491AEF0" : "ZSSRichTextEditor\/", 13 | "D4901E2DECC4ACCA927A8E9BA33FBB59E4A0AF3D" : "" 14 | }, 15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "ZSSRichTextEditor", 16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "ZSSRichTextEditor.xcodeproj", 18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 19 | { 20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/nnhubbard\/ZSSRichTextEditor.git", 21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "6C2C2B670C50C326F4CDE75C16826EDA0491AEF0" 23 | }, 24 | { 25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/bitbucket.org\/zedsaid\/simple-geocaching.git", 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "D4901E2DECC4ACCA927A8E9BA33FBB59E4A0AF3D" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRColorCursor.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2011 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #import 29 | #import "HRColorUtil.h" 30 | 31 | @interface HRColorCursor : UIView{ 32 | HRRGBColor _currentColor; 33 | } 34 | 35 | 36 | + (CGSize) cursorSize; 37 | + (float) outlineSize; 38 | + (float) shadowSize; 39 | 40 | - (id)initWithPoint:(CGPoint)point; 41 | - (void)setColorRed:(float)red andGreen:(float)green andBlue:(float)blue; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /ZSSRichTextEditor.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint ZSSRichTextEditor.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | s.name = "ZSSRichTextEditor" 12 | s.version = "0.5.2.2" 13 | s.summary = "ZSSRichTextEditor is a beautiful Rich Text WYSIWYG Editor for iOS." 14 | 15 | s.description = <<-DESC 16 | `ZSSRichTextEditor` is a beautiful Rich Text `WYSIWYG Editor` for `iOS`. It includes all of the standard editor tools one would expect from a `WYSIWYG` editor as well as an amazing source view with syntax highlighting. 17 | DESC 18 | 19 | s.homepage = "https://github.com/nnhubbard/ZSSRichTextEditor" 20 | s.screenshots = "https://camo.githubusercontent.com/2bcf02776f39cae560c57793adbd5eaf4fff9223/687474703a2f2f662e636c2e6c792f6974656d732f304c3363304e337531343251325330763159306f2f64656d6f312e676966", "https://camo.githubusercontent.com/3f9c01eba9c69d030a69faaa1a2e01a733244627/687474703a2f2f636c2e6c792f696d6167652f3369343134303367323030422f64656d6f2e676966" 21 | 22 | s.license = "MIT" 23 | 24 | s.author = { "Nic Hubbard" => "nic@zedsaid.com" } 25 | 26 | s.platform = :ios, "8.0" 27 | 28 | s.source = { :git => "https://github.com/nnhubbard/ZSSRichTextEditor.git", :tag => "0.5.2.1" } 29 | 30 | s.source_files = "**/*.{h,m}" 31 | s.exclude_files = "**/ZSSDemo*.{h,m}", "**/ZSSAppDelegate*.{h,m}", "**/main.m" 32 | s.resources = "**/ZSS*.png", "**/ZSSRichTextEditor.js", "**/editor.html", "**/jQuery.js", "**/JSBeautifier.js" 33 | 34 | s.frameworks = "CoreGraphics", "CoreText" 35 | 36 | s.requires_arc = true 37 | end 38 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/CYRToken.h: -------------------------------------------------------------------------------- 1 | // 2 | // CYRTextAttribute.h 3 | // 4 | // Version 0.2.0 5 | // 6 | // Created by Illya Busigin on 01/05/2014. 7 | // Copyright (c) 2014 Cyrillian, Inc. 8 | // 9 | // Distributed under MIT license. 10 | // Get the latest version from here: 11 | // 12 | // https://github.com/illyabusigin/CYRTextView 13 | // 14 | // The MIT License (MIT) 15 | // 16 | // Copyright (c) 2014 Cyrillian, Inc. 17 | // 18 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 19 | // this software and associated documentation files (the "Software"), to deal in 20 | // the Software without restriction, including without limitation the rights to 21 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 22 | // the Software, and to permit persons to whom the Software is furnished to do so, 23 | // subject to the following conditions: 24 | // 25 | // The above copyright notice and this permission notice shall be included in all 26 | // copies or substantial portions of the Software. 27 | // 28 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 30 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 31 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 32 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 33 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 34 | 35 | #import 36 | 37 | @interface CYRToken : NSObject 38 | 39 | @property (nonatomic, strong) NSString *name; 40 | @property (nonatomic, strong) NSString *expression; 41 | @property (nonatomic, strong) NSDictionary *attributes; 42 | 43 | + (instancetype)tokenWithName:(NSString *)name expression:(NSString *)expression attributes:(NSDictionary *)attributes; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/editor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ZSSRichTextEditor 5 | 6 | 7 | 8 | 15 | 16 | 17 | 20 | 21 | 22 | 25 | 26 | 27 | 30 | 31 | 32 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/CYRToken.m: -------------------------------------------------------------------------------- 1 | // 2 | // CYRTextAttribute.m 3 | // 4 | // Version 0.2.0 5 | // 6 | // Created by Illya Busigin on 01/05/2014. 7 | // Copyright (c) 2014 Cyrillian, Inc. 8 | // 9 | // Distributed under MIT license. 10 | // Get the latest version from here: 11 | // 12 | // https://github.com/illyabusigin/CYRTextView 13 | // 14 | // The MIT License (MIT) 15 | // 16 | // Copyright (c) 2014 Cyrillian, Inc. 17 | // 18 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 19 | // this software and associated documentation files (the "Software"), to deal in 20 | // the Software without restriction, including without limitation the rights to 21 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 22 | // the Software, and to permit persons to whom the Software is furnished to do so, 23 | // subject to the following conditions: 24 | // 25 | // The above copyright notice and this permission notice shall be included in all 26 | // copies or substantial portions of the Software. 27 | // 28 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 30 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 31 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 32 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 33 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 34 | 35 | #import "CYRToken.h" 36 | 37 | @implementation CYRToken 38 | 39 | + (instancetype)tokenWithName:(NSString *)name expression:(NSString *)expression attributes:(NSDictionary *)attributes 40 | { 41 | CYRToken *textAttribute = [CYRToken new]; 42 | 43 | textAttribute.name = name; 44 | textAttribute.expression = expression; 45 | textAttribute.attributes = attributes; 46 | 47 | return textAttribute; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/CYRLayoutManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // CYRLayoutManager.h 3 | // 4 | // Version 0.2.0 5 | // 6 | // Created by Illya Busigin on 01/05/2014. 7 | // Copyright (c) 2014 Cyrillian, Inc. 8 | // 9 | // Distributed under MIT license. 10 | // Get the latest version from here: 11 | // 12 | // https://github.com/illyabusigin/CYRTextView 13 | // Original implementation taken from: https://github.com/alldritt/TextKit_LineNumbers 14 | // 15 | // The MIT License (MIT) 16 | // 17 | // Copyright (c) 2014 Cyrillian, Inc. 18 | // 19 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 20 | // this software and associated documentation files (the "Software"), to deal in 21 | // the Software without restriction, including without limitation the rights to 22 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 23 | // the Software, and to permit persons to whom the Software is furnished to do so, 24 | // subject to the following conditions: 25 | // 26 | // The above copyright notice and this permission notice shall be included in all 27 | // copies or substantial portions of the Software. 28 | // 29 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 31 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 32 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 33 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 34 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 35 | 36 | #import 37 | 38 | @interface CYRLayoutManager : NSLayoutManager 39 | 40 | @property (nonatomic, strong) UIFont *lineNumberFont; 41 | @property (nonatomic, strong) UIColor *lineNumberColor; 42 | 43 | @property (nonatomic, readonly) CGFloat gutterWidth; 44 | @property (nonatomic, assign) NSRange selectedRange; 45 | 46 | - (CGRect)paragraphRectForRange:(NSRange)range; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/ZSSRichTextEditor-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIcons 12 | 13 | CFBundleIcons~ipad 14 | 15 | CFBundleIdentifier 16 | $(PRODUCT_BUNDLE_IDENTIFIER) 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleName 20 | ${PRODUCT_NAME} 21 | CFBundlePackageType 22 | APPL 23 | CFBundleShortVersionString 24 | 1.0 25 | CFBundleSignature 26 | ???? 27 | CFBundleVersion 28 | 1.0 29 | LSRequiresIPhoneOS 30 | 31 | NSMicrophoneUsageDescription 32 | Microphone used in ZSSRichTextEditor 33 | NSPhotoLibraryUsageDescription 34 | Photos used in ZSSRichTextEditor 35 | UILaunchStoryboardName 36 | Launch Screen 37 | UIRequiredDeviceCapabilities 38 | 39 | armv7 40 | 41 | UISupportedInterfaceOrientations 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | UIInterfaceOrientationPortraitUpsideDown 47 | 48 | UISupportedInterfaceOrientations~ipad 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationPortraitUpsideDown 52 | UIInterfaceOrientationLandscapeLeft 53 | UIInterfaceOrientationLandscapeRight 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/CYRTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CYRTextView.h 3 | // 4 | // Version 0.2.0 5 | // 6 | // Created by Illya Busigin on 01/05/2014. 7 | // Copyright (c) 2014 Cyrillian, Inc. 8 | // Copyright (c) 2013 Dominik Hauser 9 | // Copyright (c) 2013 Sam Rijs 10 | // 11 | // Distributed under MIT license. 12 | // Get the latest version from here: 13 | // 14 | // https://github.com/illyabusigin/CYRTextView 15 | // Gestures sourced from: https://github.com/srijs/NLTextView 16 | // 17 | // The MIT License (MIT) 18 | // 19 | // Copyright (c) 2014 Cyrillian, Inc. 20 | // 21 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 22 | // this software and associated documentation files (the "Software"), to deal in 23 | // the Software without restriction, including without limitation the rights to 24 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 25 | // the Software, and to permit persons to whom the Software is furnished to do so, 26 | // subject to the following conditions: 27 | // 28 | // The above copyright notice and this permission notice shall be included in all 29 | // copies or substantial portions of the Software. 30 | // 31 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 33 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 34 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 35 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 36 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37 | 38 | #import 39 | #import "CYRToken.h" 40 | 41 | @interface CYRTextView : UITextView 42 | 43 | @property (nonatomic, strong) NSArray *tokens; 44 | @property (nonatomic, strong) UIPanGestureRecognizer *singleFingerPanRecognizer; 45 | @property (nonatomic, strong) UIPanGestureRecognizer *doubleFingerPanRecognizer; 46 | 47 | @property UIColor *gutterBackgroundColor; 48 | @property UIColor *gutterLineColor; 49 | 50 | @property (nonatomic, assign) BOOL lineCursorEnabled; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /ZSSRichTextEditor.xcodeproj/project.xcworkspace/xcshareddata/ZSSRichTextEditor.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 1D85276D-8013-471B-8035-FD0DD32B9643 9 | IDESourceControlProjectName 10 | ZSSRichTextEditor 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 6C2C2B670C50C326F4CDE75C16826EDA0491AEF0 14 | https://github.com/nnhubbard/ZSSRichTextEditor.git 15 | D4901E2DECC4ACCA927A8E9BA33FBB59E4A0AF3D 16 | https://bitbucket.org/zedsaid/simple-geocaching.git 17 | 18 | IDESourceControlProjectPath 19 | ZSSRichTextEditor.xcodeproj 20 | IDESourceControlProjectRelativeInstallPathDictionary 21 | 22 | 6C2C2B670C50C326F4CDE75C16826EDA0491AEF0 23 | ../.. 24 | D4901E2DECC4ACCA927A8E9BA33FBB59E4A0AF3D 25 | ../../.. 26 | 27 | IDESourceControlProjectURL 28 | https://github.com/nnhubbard/ZSSRichTextEditor.git 29 | IDESourceControlProjectVersion 30 | 111 31 | IDESourceControlProjectWCCIdentifier 32 | 6C2C2B670C50C326F4CDE75C16826EDA0491AEF0 33 | IDESourceControlProjectWCConfigurations 34 | 35 | 36 | IDESourceControlRepositoryExtensionIdentifierKey 37 | public.vcs.git 38 | IDESourceControlWCCIdentifierKey 39 | D4901E2DECC4ACCA927A8E9BA33FBB59E4A0AF3D 40 | IDESourceControlWCCName 41 | 42 | 43 | 44 | IDESourceControlRepositoryExtensionIdentifierKey 45 | public.vcs.git 46 | IDESourceControlWCCIdentifierKey 47 | 6C2C2B670C50C326F4CDE75C16826EDA0491AEF0 48 | IDESourceControlWCCName 49 | ZSSRichTextEditor 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSCustomButtonsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSCustomButtonsViewController.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 8/14/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSCustomButtonsViewController.h" 10 | #import "ZSSBarButtonItem.h" 11 | 12 | @interface ZSSCustomButtonsViewController () 13 | 14 | @end 15 | 16 | @implementation ZSSCustomButtonsViewController 17 | 18 | 19 | - (void)viewDidLoad 20 | { 21 | [super viewDidLoad]; 22 | 23 | 24 | self.title = @"Custom Buttons"; 25 | 26 | // HTML Content to set in the editor 27 | NSString *html = @"

This editor is using custom buttons.

"; 28 | 29 | // Set the HTML contents of the editor 30 | [self setHTML:html]; 31 | 32 | // Don't allow editor toolbar buttons (you can if you want) 33 | self.enabledToolbarItems = @[ZSSRichTextEditorToolbarNone]; 34 | 35 | // Create the custom buttons 36 | UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 50, 28.0f)]; 37 | [myButton setTitle:@"Test" forState:UIControlStateNormal]; 38 | [myButton addTarget:self 39 | action:@selector(didTapCustomToolbarButton:) 40 | forControlEvents:UIControlEventTouchUpInside]; 41 | [self addCustomToolbarItemWithButton:myButton]; 42 | 43 | // Custom image button 44 | ZSSBarButtonItem *item = [[ZSSBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ZSSinsertkeyword.png"] style:UIBarButtonItemStylePlain target:self action:@selector(didTapCustomToolbarButton:)]; 45 | [self addCustomToolbarItem:item]; 46 | 47 | } 48 | 49 | 50 | - (void)didTapCustomToolbarButton:(UIButton *)button { 51 | 52 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Custom Button!" 53 | message:nil 54 | delegate:self 55 | cancelButtonTitle:NSLocalizedString(@"Cancel", nil) 56 | otherButtonTitles:nil]; 57 | [alertView show]; 58 | 59 | } 60 | 61 | 62 | - (void)didReceiveMemoryWarning 63 | { 64 | [super didReceiveMemoryWarning]; 65 | // Dispose of any resources that can be recreated. 66 | } 67 | 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSDemoPickerViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSDemoPickerViewController.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 1/30/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSDemoPickerViewController.h" 10 | 11 | 12 | @interface ZSSDemoPickerViewController () 13 | @property (nonatomic, strong) UITextField *textField; 14 | @end 15 | 16 | @implementation ZSSDemoPickerViewController 17 | 18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 19 | { 20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 21 | if (self) { 22 | // Custom initialization 23 | } 24 | return self; 25 | } 26 | 27 | - (void)viewDidLoad 28 | { 29 | [super viewDidLoad]; 30 | // Do any additional setup after loading the view. 31 | 32 | self.title = @"Picker"; 33 | self.view.backgroundColor = [UIColor whiteColor]; 34 | UIBarButtonItem *save = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveURL)]; 35 | self.navigationItem.rightBarButtonItem = save; 36 | 37 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel)]; 38 | 39 | self.textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, self.view.frame.size.width - 40, 40)]; 40 | self.textField.text = !self.isInsertImagePicker ? @"http://www.apple.com" : @"http://fineprintnyc.com/images/blog/history-of-apple-logo/apple-logo-2.jpg"; 41 | self.textField.layer.borderColor = [UIColor grayColor].CGColor; 42 | self.textField.layer.borderWidth = 0.5f; 43 | self.textField.clearButtonMode = UITextFieldViewModeAlways; 44 | [self.view addSubview:self.textField]; 45 | 46 | } 47 | 48 | - (void)cancel { 49 | [self dismissViewControllerAnimated:YES completion:nil]; 50 | } 51 | 52 | - (void)saveURL { 53 | 54 | [self dismissViewControllerAnimated:YES completion:nil]; 55 | 56 | ZSSDemoViewController *vc = self.demoView; 57 | if (!self.isInsertImagePicker) { 58 | [vc showInsertLinkDialogWithLink:self.textField.text title:nil]; 59 | } else { 60 | [vc showInsertImageDialogWithLink:self.textField.text alt:nil]; 61 | } 62 | 63 | } 64 | 65 | - (void)didReceiveMemoryWarning 66 | { 67 | [super didReceiveMemoryWarning]; 68 | // Dispose of any resources that can be recreated. 69 | } 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSAppDelegate.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 11/28/13. 6 | // Copyright (c) 2013 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSAppDelegate.h" 10 | 11 | @implementation ZSSAppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 16 | // Override point for customization after application launch. 17 | self.mainViewController = [[ZSSDemoList alloc] init]; 18 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self.mainViewController]; 19 | nav.navigationBar.translucent = NO; 20 | self.window.rootViewController = nav; 21 | self.window.backgroundColor = [UIColor whiteColor]; 22 | [self.window makeKeyAndVisible]; 23 | return YES; 24 | } 25 | 26 | - (void)applicationWillResignActive:(UIApplication *)application 27 | { 28 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 29 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 30 | } 31 | 32 | - (void)applicationDidEnterBackground:(UIApplication *)application 33 | { 34 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 36 | } 37 | 38 | - (void)applicationWillEnterForeground:(UIApplication *)application 39 | { 40 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 41 | } 42 | 43 | - (void)applicationDidBecomeActive:(UIApplication *)application 44 | { 45 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 46 | } 47 | 48 | - (void)applicationWillTerminate:(UIApplication *)application 49 | { 50 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-Notification@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-Notification@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-Small@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-Small@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-Small-40@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-Small-40@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-60@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-60@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "20x20", 53 | "idiom" : "ipad", 54 | "filename" : "Icon-Notification.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-Notification@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-Small.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-Small@2x.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-Small-40.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-Small-40@2x.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-76.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-76@2x.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-83.5@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "1024x1024", 107 | "idiom" : "ios-marketing", 108 | "filename" : "icon.png", 109 | "scale" : "1x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "xcode" 115 | } 116 | } -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRColorUtil.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2011 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #import 29 | 30 | ///////////////////////////////////////////////////////////////////////////// 31 | // 32 | // 0.0f~1.0fの値をとるRGBの構造体です 33 | // 34 | ///////////////////////////////////////////////////////////////////////////// 35 | 36 | typedef struct{ 37 | float r; 38 | float g; 39 | float b; 40 | } HRRGBColor; 41 | 42 | ///////////////////////////////////////////////////////////////////////////// 43 | // 44 | // 0.0f~1.0fの値をとるHSVの構造体です 45 | // 46 | ///////////////////////////////////////////////////////////////////////////// 47 | 48 | typedef struct{ 49 | float h; 50 | float s; 51 | float v; 52 | } HRHSVColor; 53 | 54 | // 値のチェックしてません。数値として入れさせるなら自前でチェックして下さい。 55 | 56 | ///////////////////////////////////////////////////////////////////////////// 57 | // 58 | // 変換用の関数 59 | // 60 | ///////////////////////////////////////////////////////////////////////////// 61 | 62 | void HSVColorFromRGBColor(const HRRGBColor*,HRHSVColor*); 63 | void RGBColorFromHSVColor(const HRHSVColor*,HRRGBColor*); 64 | void RGBColorFromUIColor(const UIColor*,HRRGBColor*); 65 | 66 | // 16進数のカラーコードを取得 (例:#ffffff) 67 | // NSString* hexColorStr = [NSString stringWithFormat:@"#%06x",HexColorFromUIColor([UIColor redColor])]; で文字列に変換されます 68 | int HexColorFromRGBColor(const HRRGBColor*); 69 | int HexColorFromUIColor(const UIColor*); 70 | 71 | 72 | // 同値チェック 73 | bool HRHSVColorEqualToColor(const HRHSVColor*,const HRHSVColor*); 74 | 75 | 76 | // 0.0f~1.0fに納まるxとy、彩度の下限、輝度からHSVを求める 77 | void HSVColorAt(HRHSVColor* hsv,float x,float y,float saturationLowerLimit,float brightness); 78 | 79 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRColorPickerViewController.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2011 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #import 29 | #import "HRColorPickerMacros.h" 30 | 31 | @class HRColorPickerView; 32 | 33 | @protocol HRColorPickerViewControllerDelegate 34 | - (void)setSelectedColor:(UIColor*)color tag:(int)tag; 35 | @end 36 | 37 | #define HRColorPickerDelegate HRColorPickerViewControllerDelegate 38 | // Delegateの名前変えました。すみません。 39 | 40 | typedef enum { 41 | HCPCSaveStyleSaveAlways, 42 | HCPCSaveStyleSaveAndCancel 43 | } HCPCSaveStyle; 44 | 45 | @interface HRColorPickerViewController : UIViewController { 46 | id __weak delegate; 47 | HRColorPickerView* colorPickerView; 48 | 49 | UIColor *_color; 50 | BOOL _fullColor; 51 | HCPCSaveStyle _saveStyle; 52 | 53 | } 54 | 55 | @property (nonatomic) int tag; 56 | 57 | + (HRColorPickerViewController *)colorPickerViewControllerWithColor:(UIColor *)color; 58 | + (HRColorPickerViewController *)cancelableColorPickerViewControllerWithColor:(UIColor *)color; 59 | + (HRColorPickerViewController *)fullColorPickerViewControllerWithColor:(UIColor *)color; 60 | + (HRColorPickerViewController *)cancelableFullColorPickerViewControllerWithColor:(UIColor *)color; 61 | 62 | /** Initialize controller with selected color. 63 | * @param defaultColor selected color 64 | * @param fullColor If YES, browseable full color. If NO color was limited. 65 | * @param saveStyle If it's HCPCSaveStyleSaveAlways, save color when self is closing. If it's HCPCSaveStyleSaveAndCancel, shows Cancel and Save button. 66 | */ 67 | - (id)initWithColor:(UIColor*)defaultColor fullColor:(BOOL)fullColor saveStyle:(HCPCSaveStyle)saveStyle; 68 | 69 | /** @deprecated use -save: instead of this . */ 70 | - (void)saveColor:(id)sender; 71 | 72 | - (void)save; 73 | - (void)save:(id)sender; 74 | - (void)cancel:(id)sender; 75 | 76 | 77 | @property (weak) id delegate; 78 | 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRColorCursor.m: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2011 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #import "HRColorCursor.h" 29 | #import "HRCgUtil.h" 30 | 31 | @implementation HRColorCursor 32 | 33 | + (CGSize) cursorSize 34 | { 35 | return CGSizeMake(30.0, 30.0f); 36 | } 37 | 38 | + (float) outlineSize 39 | { 40 | return 4.0f; 41 | } 42 | 43 | + (float) shadowSize 44 | { 45 | return 2.0f; 46 | } 47 | 48 | 49 | - (id)initWithPoint:(CGPoint)point 50 | { 51 | CGSize size = [HRColorCursor cursorSize]; 52 | CGRect frame = CGRectMake(point.x, point.y, size.width, size.height); 53 | self = [super initWithFrame:frame]; 54 | if (self) { 55 | [self setBackgroundColor:[UIColor clearColor]]; 56 | [self setUserInteractionEnabled:FALSE]; 57 | _currentColor.r = _currentColor.g = _currentColor.b = 1.0f; 58 | } 59 | return self; 60 | } 61 | 62 | - (void)setColorRed:(float)red andGreen:(float)green andBlue:(float)blue{ 63 | _currentColor.r = red; 64 | _currentColor.g = green; 65 | _currentColor.b = blue; 66 | [self setNeedsDisplay]; 67 | } 68 | 69 | - (void)drawRect:(CGRect)rect 70 | { 71 | CGContextRef context = UIGraphicsGetCurrentContext(); 72 | float outlineSize = [HRColorCursor outlineSize]; 73 | CGSize cursorSize = [HRColorCursor cursorSize]; 74 | float shadowSize = [HRColorCursor shadowSize]; 75 | 76 | CGContextSaveGState(context); 77 | HRSetRoundedRectanglePath(context, CGRectMake(shadowSize, shadowSize, cursorSize.width - shadowSize*2.0f, cursorSize.height - shadowSize*2.0f), 2.0f); 78 | [[UIColor whiteColor] set]; 79 | CGContextSetShadow(context, CGSizeMake(0.0f, 1.0f), shadowSize); 80 | CGContextDrawPath(context, kCGPathFill); 81 | CGContextRestoreGState(context); 82 | 83 | 84 | [[UIColor colorWithRed:_currentColor.r green:_currentColor.g blue:_currentColor.b alpha:1.0f] set]; 85 | CGContextFillRect(context, CGRectMake(outlineSize + shadowSize, outlineSize + shadowSize, cursorSize.width - (outlineSize + shadowSize)*2.0f, cursorSize.height - (outlineSize + shadowSize)*2.0f)); 86 | } 87 | 88 | 89 | @end 90 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Launch Screen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSDemoViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSDemoViewController.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 11/29/13. 6 | // Copyright (c) 2013 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSDemoViewController.h" 10 | #import "ZSSDemoPickerViewController.h" 11 | 12 | 13 | #import "DemoModalViewController.h" 14 | 15 | 16 | @interface ZSSDemoViewController () 17 | 18 | @end 19 | 20 | @implementation ZSSDemoViewController 21 | 22 | 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | 26 | self.title = @"Standard"; 27 | 28 | //Set Custom CSS 29 | NSString *customCSS = @""; 30 | [self setCSS:customCSS]; 31 | 32 | self.alwaysShowToolbar = YES; 33 | self.receiveEditorDidChangeEvents = NO; 34 | 35 | // Export HTML 36 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Export" style:UIBarButtonItemStylePlain target:self action:@selector(exportHTML)]; 37 | 38 | // HTML Content to set in the editor 39 | NSString *html = @"
" 40 | "

This is a test of the ZSSRichTextEditor by Zed Said Studio

"; 41 | 42 | // Set the base URL if you would like to use relative links, such as to images. 43 | self.baseURL = [NSURL URLWithString:@"http://www.zedsaid.com"]; 44 | self.shouldShowKeyboard = NO; 45 | // Set the HTML contents of the editor 46 | [self setPlaceholder:@"This is a placeholder that will show when there is no content(html)"]; 47 | 48 | [self setHTML:html]; 49 | 50 | } 51 | 52 | 53 | - (void)showInsertURLAlternatePicker { 54 | 55 | [self dismissAlertView]; 56 | 57 | ZSSDemoPickerViewController *picker = [[ZSSDemoPickerViewController alloc] init]; 58 | picker.demoView = self; 59 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:picker]; 60 | nav.navigationBar.translucent = NO; 61 | [self presentViewController:nav animated:YES completion:nil]; 62 | 63 | } 64 | 65 | 66 | - (void)showInsertImageAlternatePicker { 67 | 68 | [self dismissAlertView]; 69 | 70 | ZSSDemoPickerViewController *picker = [[ZSSDemoPickerViewController alloc] init]; 71 | picker.demoView = self; 72 | picker.isInsertImagePicker = YES; 73 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:picker]; 74 | nav.navigationBar.translucent = NO; 75 | [self presentViewController:nav animated:YES completion:nil]; 76 | 77 | } 78 | 79 | 80 | - (void)exportHTML { 81 | [self getHTML:^(NSString *result, NSError * _Nullable error) { 82 | NSLog(@"%@", result); 83 | }]; 84 | } 85 | 86 | - (void)editorDidChangeWithText:(NSString *)text andHTML:(NSString *)html { 87 | 88 | NSLog(@"Text Has Changed: %@", text); 89 | 90 | NSLog(@"HTML Has Changed: %@", html); 91 | 92 | } 93 | 94 | - (void)hashtagRecognizedWithWord:(NSString *)word { 95 | 96 | NSLog(@"Hashtag has been recognized: %@", word); 97 | 98 | } 99 | 100 | - (void)mentionRecognizedWithWord:(NSString *)word { 101 | 102 | NSLog(@"Mention has been recognized: %@", word); 103 | 104 | } 105 | 106 | - (void)didReceiveMemoryWarning 107 | { 108 | [super didReceiveMemoryWarning]; 109 | // Dispose of any resources that can be recreated. 110 | } 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRCgUtil.m: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2011 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #import "HRCgUtil.h" 29 | 30 | void HRSetRoundedRectanglePath(CGContextRef context,const CGRect rect,CGFloat radius){ 31 | CGFloat lx = CGRectGetMinX(rect); 32 | CGFloat cx = CGRectGetMidX(rect); 33 | CGFloat rx = CGRectGetMaxX(rect); 34 | CGFloat by = CGRectGetMinY(rect); 35 | CGFloat cy = CGRectGetMidY(rect); 36 | CGFloat ty = CGRectGetMaxY(rect); 37 | 38 | CGContextMoveToPoint(context, lx, cy); 39 | CGContextAddArcToPoint(context, lx, by, cx, by, radius); 40 | CGContextAddArcToPoint(context, rx, by, rx, cy, radius); 41 | CGContextAddArcToPoint(context, rx, ty, cx, ty, radius); 42 | CGContextAddArcToPoint(context, lx, ty, lx, cy, radius); 43 | CGContextClosePath(context); 44 | } 45 | 46 | void HRDrawSquareColorBatch(CGContextRef context,CGPoint position,HRRGBColor* color,float size){ 47 | float cx = position.x; 48 | float cy = position.y; 49 | 50 | float rRize = size; 51 | float backRSize = rRize + 3.0f; 52 | float shadowRSize = backRSize + 3.0f; 53 | 54 | CGRect rectEllipse = CGRectMake(cx - rRize, cy - rRize, rRize*2, rRize*2); 55 | CGRect rectBackEllipse = CGRectMake(cx - backRSize, cy - backRSize, backRSize*2, backRSize*2); 56 | CGRect rectShadowEllipse = CGRectMake(cx - shadowRSize, cy - shadowRSize, shadowRSize*2, shadowRSize*2); 57 | 58 | CGContextSaveGState(context); 59 | HRSetRoundedRectanglePath(context, rectBackEllipse,8.0f); 60 | CGContextClip(context); 61 | HRSetRoundedRectanglePath(context, rectShadowEllipse,8.0f); 62 | CGContextSetLineWidth(context, 5.5f); 63 | [[UIColor whiteColor] set]; 64 | CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 1.0f), 4.0f, [UIColor colorWithWhite:0.0f alpha:0.2f].CGColor); 65 | CGContextDrawPath(context, kCGPathStroke); 66 | CGContextRestoreGState(context); 67 | 68 | CGContextSaveGState(context); 69 | CGContextSetRGBFillColor(context, color->r, color->g, color->b, 1.0f); 70 | CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 0.5f), 0.5f, [UIColor colorWithWhite:0.0f alpha:0.2f].CGColor); 71 | HRSetRoundedRectanglePath(context, rectEllipse,5.0f); 72 | CGContextDrawPath(context, kCGPathFill); 73 | CGContextRestoreGState(context); 74 | } -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSLargeViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSLargeViewController.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 8/13/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSLargeViewController.h" 10 | 11 | @interface ZSSLargeViewController () 12 | 13 | @end 14 | 15 | @implementation ZSSLargeViewController 16 | 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | 22 | self.title = @"Large"; 23 | 24 | self.alwaysShowToolbar = YES; 25 | 26 | // HTML Content to set in the editor 27 | NSString *html = @"

Large Editor

" 28 | "

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam at enim at nibh pulvinar sagittis eu non lacus. Quisque suscipit tempor urna vel pretium. Curabitur id enim auctor, cursus elit ac, porttitor sem. Ut suscipit purus odio, vitae sollicitudin sapien placerat in. Duis adipiscing urna id viverra tincidunt. Duis sit amet adipiscing justo, vitae facilisis ipsum. Vivamus scelerisque justo ut libero dictum, id tempor ipsum tempus. Nam nec dui dapibus, tristique dolor et, sollicitudin enim. Nullam sagittis arcu tortor, mollis porta mi laoreet ac. Proin lobortis bibendum urna, in ultrices dolor hendrerit quis. Morbi felis quam, luctus nec suscipit porttitor, lacinia vitae velit. Nulla ultricies pellentesque porta. Suspendisse suscipit sagittis metus non rhoncus.

" 29 | "

Phasellus adipiscing justo ipsum, eget feugiat dui elementum id. Pellentesque eu dolor eu arcu bibendum sollicitudin. Aenean ac dolor non lectus laoreet semper at vel est. Curabitur sit amet odio laoreet turpis mattis suscipit at sed lacus. Nunc tincidunt ipsum nulla, ac blandit leo lobortis eu. Curabitur mauris mauris, vestibulum at urna sit amet, condimentum venenatis ante. Nullam a risus nisi. Donec sit amet imperdiet mi.

" 30 | "

Sed in lorem luctus lorem feugiat viverra facilisis ut velit. Maecenas convallis leo purus. Integer vestibulum mi eget quam auctor vehicula. Phasellus id eleifend nunc. Mauris pretium blandit orci a accumsan. Aliquam hendrerit sit amet ligula et dignissim. Pellentesque feugiat scelerisque sapien nec scelerisque. Nunc ac placerat lectus. Proin sed dolor in leo congue facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque arcu velit, tempus sit amet elit at, aliquet iaculis dolor. Nam eget sollicitudin libero. Mauris dignissim, risus sit amet tempor tempus, risus mauris faucibus massa, sed elementum mauris turpis et arcu.

" 31 | "

Aliquam mattis libero arcu, a ultrices risus mattis sed. Vivamus facilisis consectetur ipsum at volutpat. Duis eget lorem sodales, congue libero dapibus, dignissim odio. Vivamus hendrerit ante at metus feugiat fringilla. Quisque imperdiet magna in tristique sagittis. Nulla neque turpis, tempus a leo eget, auctor interdum dui. In porta mi non libero lacinia pulvinar. Nunc a augue eget est malesuada eleifend a et orci. Aenean in tempus purus. Curabitur auctor viverra massa. Proin in justo pretium lacus pretium ullamcorper. Morbi elementum leo nibh, quis sodales nibh scelerisque ut.

" 32 | "

Mauris sed consequat augue. Aliquam accumsan erat lacus, consequat volutpat augue imperdiet vitae. Sed tempus dui quis faucibus tempor. Aliquam ultricies in turpis et vehicula. Suspendisse potenti. Duis iaculis rhoncus enim sed tempus. Cras non metus sed erat accumsan gravida vitae in lacus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer vel cursus ligula, a auctor lacus. In rhoncus massa varius sagittis ultrices. Donec aliquam, nisl sit amet hendrerit pretium, lorem quam mollis purus, ac interdum elit mi et neque. Etiam porta rutrum lacinia. Nullam nec vestibulum ligula. Nam nec ipsum odio. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

"; 33 | 34 | // Set the HTML contents of the editor 35 | [self setHTML:html]; 36 | 37 | } 38 | 39 | 40 | 41 | - (void)didReceiveMemoryWarning 42 | { 43 | [super didReceiveMemoryWarning]; 44 | // Dispose of any resources that can be recreated. 45 | } 46 | 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRBrightnessCursor.m: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2011 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #import "HRBrightnessCursor.h" 29 | #import "HRCgUtil.h" 30 | 31 | @implementation HRBrightnessCursor 32 | 33 | - (id)initWithPoint:(CGPoint)point 34 | { 35 | CGSize size = CGSizeMake(18.0f, 40.0f); 36 | CGRect frame = CGRectMake(point.x - size.width/2.0f, point.y - size.height/2.0f, size.width, size.height); 37 | self = [super initWithFrame:frame]; 38 | if (self) { 39 | [self setBackgroundColor:[UIColor clearColor]]; 40 | [self setUserInteractionEnabled:FALSE]; 41 | } 42 | return self; 43 | } 44 | 45 | - (void)drawRect:(CGRect)rect 46 | { 47 | CGContextRef context = UIGraphicsGetCurrentContext(); 48 | 49 | CGContextSaveGState(context); 50 | HRSetRoundedRectanglePath(context, CGRectMake(2.0f, 13.0f, 14.0f, 14.0f), 2.0f); 51 | [[UIColor colorWithWhite:0.98f alpha:1.0f] set]; 52 | CGContextSetLineWidth(context, 2.0f); 53 | CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 1.0f), 2.0f, [UIColor colorWithWhite:0.0f alpha:0.3f].CGColor); 54 | CGContextDrawPath(context, kCGPathFillStroke); 55 | 56 | CGContextRestoreGState(context); 57 | 58 | CGContextSaveGState(context); 59 | HRSetRoundedRectanglePath(context, CGRectMake(2.0f, 13.0f, 14.0f, 14.0f), 2.0f); 60 | CGContextClip(context); 61 | 62 | float top_color = 0.9f; 63 | float bottom_color = 0.98f; 64 | float alpha = 1.0f; 65 | CGFloat gradient_color[] = { 66 | top_color ,top_color ,top_color ,alpha, 67 | bottom_color ,bottom_color ,bottom_color ,alpha 68 | }; 69 | CGGradientRef gradient; 70 | CGColorSpaceRef colorSpace; 71 | size_t num_locations = 2; 72 | CGFloat locations[2] = { 0.0, 1.0 }; 73 | colorSpace = CGColorSpaceCreateDeviceRGB(); 74 | gradient = CGGradientCreateWithColorComponents(colorSpace, gradient_color, 75 | locations, num_locations); 76 | 77 | CGPoint startPoint = CGPointMake(self.frame.size.width/2, 0.0); 78 | CGPoint endPoint = CGPointMake(self.frame.size.width/2, self.frame.size.height); 79 | CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0); 80 | 81 | // GradientとColorSpaceを開放する 82 | CGColorSpaceRelease(colorSpace); 83 | CGGradientRelease(gradient); 84 | 85 | CGContextRestoreGState(context); 86 | 87 | CGContextSaveGState(context); 88 | [[UIColor colorWithWhite:1.0f alpha:1.0f] setStroke]; 89 | CGContextMoveToPoint(context, 6.0f, 17.0f); 90 | CGContextAddLineToPoint(context, 6.0f, 24.0f); 91 | CGContextMoveToPoint(context, 9.0f, 17.0f); 92 | CGContextAddLineToPoint(context, 9.0f, 24.0f); 93 | CGContextMoveToPoint(context, 12.0f, 17.0f); 94 | CGContextAddLineToPoint(context, 12.0f, 24.0f); 95 | CGContextDrawPath(context, kCGPathStroke); 96 | 97 | CGContextRestoreGState(context); 98 | 99 | } 100 | 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Classes/ZSSDemoList.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSDemoList.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 8/12/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSDemoList.h" 10 | #import "ZSSDemoViewController.h" 11 | #import "ZSSColorViewController.h" 12 | #import "ZSSLargeViewController.h" 13 | #import "ZSSPlaceholderViewController.h" 14 | #import "ZSSSelectiveViewController.h" 15 | #import "ZSSCustomButtonsViewController.h" 16 | 17 | @interface ZSSDemoList () 18 | @property (nonatomic) BOOL isIPad; 19 | @end 20 | 21 | @implementation ZSSDemoList 22 | 23 | - (id)initWithStyle:(UITableViewStyle)style 24 | { 25 | self = [super initWithStyle:style]; 26 | if (self) { 27 | // Custom initialization 28 | } 29 | return self; 30 | } 31 | 32 | - (void)viewDidLoad 33 | { 34 | [super viewDidLoad]; 35 | 36 | self.title = @"ZSSRichTextEditor Demo"; 37 | 38 | self.isIPad = ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ); 39 | 40 | } 41 | 42 | - (void)didReceiveMemoryWarning 43 | { 44 | [super didReceiveMemoryWarning]; 45 | // Dispose of any resources that can be recreated. 46 | } 47 | 48 | #pragma mark - Table view data source 49 | 50 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 51 | { 52 | // Return the number of sections. 53 | return 1; 54 | } 55 | 56 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 57 | { 58 | // Return the number of rows in the section. 59 | //if (self.isIPad) return 6; 60 | return 5; 61 | } 62 | 63 | 64 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 65 | { 66 | 67 | static NSString *cellID = @"Cell Identifier"; 68 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; 69 | if (!cell) 70 | { 71 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]; 72 | cell.selectionStyle = UITableViewCellSelectionStyleGray; 73 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 74 | } 75 | 76 | if (indexPath.row == 0) { 77 | cell.textLabel.text = @"Standard"; 78 | cell.detailTextLabel.text = @"Default implementation"; 79 | } else if (indexPath.row == 1) { 80 | cell.textLabel.text = @"Toolbar Colors"; 81 | cell.detailTextLabel.text = @"Custom button and selected button colors"; 82 | } else if (indexPath.row == 2) { 83 | cell.textLabel.text = @"Selective Buttons"; 84 | cell.detailTextLabel.text = @"Pick and choose the features you want"; 85 | } else if (indexPath.row == 3) { 86 | cell.textLabel.text = @"Custom Buttons"; 87 | cell.detailTextLabel.text = @"Add your own customized toolbar button"; 88 | } else if (indexPath.row == 4) { 89 | cell.textLabel.text = @"Large"; 90 | cell.detailTextLabel.text = @"A large amount of content in the editor"; 91 | } else if (indexPath.row == 5) { 92 | cell.textLabel.text = @"iPad Form Style Modal"; 93 | cell.detailTextLabel.text = @"Shows a form style modal on the iPad"; 94 | } 95 | cell.detailTextLabel.textColor = [UIColor grayColor]; 96 | 97 | return cell; 98 | } 99 | 100 | 101 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 102 | 103 | if (indexPath.row == 0) { 104 | ZSSDemoViewController *demo1 = [[ZSSDemoViewController alloc] init]; 105 | [self.navigationController pushViewController:demo1 animated:YES]; 106 | } else if (indexPath.row == 1) { 107 | ZSSColorViewController *demo2 = [[ZSSColorViewController alloc] init]; 108 | [self.navigationController pushViewController:demo2 animated:YES]; 109 | } else if (indexPath.row == 2) { 110 | ZSSSelectiveViewController *demo3 = [[ZSSSelectiveViewController alloc] init]; 111 | [self.navigationController pushViewController:demo3 animated:YES]; 112 | } else if (indexPath.row == 3) { 113 | ZSSCustomButtonsViewController *demo4 = [[ZSSCustomButtonsViewController alloc] init]; 114 | [self.navigationController pushViewController:demo4 animated:YES]; 115 | } else if (indexPath.row == 4) { 116 | ZSSLargeViewController *demo5 = [[ZSSLargeViewController alloc] init]; 117 | [self.navigationController pushViewController:demo5 animated:YES]; 118 | } else if (indexPath.row == 5) { 119 | ZSSDemoViewController *demo1 = [[ZSSDemoViewController alloc] init]; 120 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:demo1]; 121 | nav.modalPresentationStyle = UIModalPresentationFormSheet; 122 | [self presentViewController:nav animated:YES completion:nil]; 123 | } 124 | 125 | } 126 | 127 | @end 128 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRColorPickerView.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2011 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #import 29 | #import 30 | #import 31 | #import "HRColorUtil.h" 32 | #import "HRColorPickerMacros.h" 33 | 34 | @class HRColorPickerView; 35 | 36 | @protocol HRColorPickerViewDelegate 37 | - (void)colorWasChanged:(HRColorPickerView*)color_picker_view; 38 | @end 39 | 40 | typedef struct timeval timeval; 41 | 42 | struct HRColorPickerStyle{ 43 | float width; // viewの横幅。デフォルトは320.0f; 44 | float headerHeight; // 明度スライダーを含むヘッダ部分の高さ(デフォルトは106.0f。70.0fくらいが下限になると思います) 45 | float colorMapTileSize; // カラーマップの中のタイルのサイズ。デフォルトは15.0f; 46 | int colorMapSizeWidth; // カラーマップの中にいくつのタイルが並ぶか (not view.width)。デフォルトは20; 47 | int colorMapSizeHeight; // 同じく縦にいくつ並ぶか。デフォルトは20; 48 | float brightnessLowerLimit; // 明度の下限 49 | float saturationUpperLimit; // 彩度の上限 50 | }; 51 | 52 | typedef struct HRColorPickerStyle HRColorPickerStyle; 53 | 54 | @class HRBrightnessCursor; 55 | @class HRColorCursor; 56 | 57 | @interface HRColorPickerView : UIControl{ 58 | NSObject* __weak delegate; 59 | @private 60 | bool _animating; 61 | 62 | // 入力関係 63 | bool _isTapStart; 64 | bool _isTapped; 65 | bool _wasDragStart; 66 | bool _isDragStart; 67 | bool _isDragging; 68 | bool _isDragEnd; 69 | 70 | CGPoint _activeTouchPosition; 71 | CGPoint _touchStartPosition; 72 | 73 | // 色情報 74 | HRRGBColor _defaultRgbColor; 75 | HRHSVColor _currentHsvColor; 76 | 77 | // カラーマップ上のカーソルの位置 78 | CGPoint _colorCursorPosition; 79 | 80 | // パーツの配置 81 | CGRect _currentColorFrame; 82 | CGRect _brightnessPickerFrame; 83 | CGRect _brightnessPickerTouchFrame; 84 | CGRect _brightnessPickerShadowFrame; 85 | CGRect _colorMapFrame; 86 | CGRect _colorMapSideFrame; 87 | float _tileSize; 88 | float _brightnessLowerLimit; 89 | float _saturationUpperLimit; 90 | 91 | HRBrightnessCursor* _brightnessCursor; 92 | HRColorCursor* _colorCursor; 93 | 94 | // キャッシュ 95 | CGImageRef _brightnessPickerShadowImage; 96 | 97 | // フレームレート 98 | timeval _lastDrawTime; 99 | timeval _timeInterval15fps; 100 | 101 | bool _delegateHasSELColorWasChanged; 102 | } 103 | 104 | // スタイルを取得 105 | + (HRColorPickerStyle)defaultStyle; 106 | + (HRColorPickerStyle)fullColorStyle; 107 | 108 | // j5136p1 12/08/2014 : Extended the method with size to fit the current view 109 | + (HRColorPickerStyle)fitScreenStyleWithSize:(CGSize)size; // iPhone5以降の縦長スクリーンに対応しています。 110 | 111 | // j5136p1 12/08/2014 : Extended the method with size to fit the current view 112 | + (HRColorPickerStyle)fitScreenFullColorStyleWithSize:(CGSize)size; 113 | 114 | // スタイルからviewのサイズを取得 115 | + (CGSize)sizeWithStyle:(HRColorPickerStyle)style; 116 | 117 | // スタイルを指定してデフォルトカラーで初期化 118 | - (id)initWithStyle:(HRColorPickerStyle)style defaultColor:(const HRRGBColor)defaultColor; 119 | 120 | // デフォルトカラーで初期化 (互換性のために残していますが、frameが反映されません) 121 | - (id)initWithFrame:(CGRect)frame defaultColor:(const HRRGBColor)defaultColor; 122 | 123 | // 現在選択している色をRGBで返す 124 | - (HRRGBColor)RGBColor; 125 | 126 | // 後方互換性のため。呼び出す必要はありません。 127 | - (void)BeforeDealloc; 128 | 129 | @property (getter = BrightnessLowerLimit, setter = setBrightnessLowerLimit:) float BrightnessLowerLimit; 130 | @property (getter = SaturationUpperLimit, setter = setSaturationUpperLimit:) float SaturationUpperLimit; 131 | @property (nonatomic, weak) NSObject* delegate; 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRColorUtil.m: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2011 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #import "HRColorUtil.h" 29 | 30 | void HSVColorFromRGBColor(const HRRGBColor* rgb,HRHSVColor* hsv){ 31 | HRRGBColor rgb255 = {rgb->r * 255.0f,rgb->g * 255.0f,rgb->b * 255.0f}; 32 | HRHSVColor hsv255 = {0.0f,0.0f,0.0f}; 33 | 34 | float max = rgb255.r; 35 | if (max < rgb255.g) { 36 | max = rgb255.g; 37 | } 38 | if (max < rgb255.b) { 39 | max = rgb255.b; 40 | } 41 | hsv255.v = max; 42 | 43 | float min = rgb255.r; 44 | if (min > rgb255.g) { 45 | min = rgb255.g; 46 | } 47 | if (min > rgb255.b) { 48 | min = rgb255.b; 49 | } 50 | 51 | if (max == 0.0f) { 52 | hsv255.h = 0.0f; 53 | hsv255.s = 0.0f; 54 | }else{ 55 | hsv255.s = 255*(max - min)/(double)max; 56 | int h = 0.0f; 57 | if(max == rgb255.r){ 58 | h = 60 * (rgb255.g - rgb255.b) / (double)(max - min); 59 | }else if(max == rgb255.g){ 60 | h = 60 * (rgb255.b - rgb255.r) / (double)(max - min) + 120; 61 | }else{ 62 | h = 60 * (rgb255.r - rgb255.g) / (double)(max - min) + 240; 63 | } 64 | if(h < 0) h += 360; 65 | hsv255.h = (float)h; 66 | } 67 | hsv->h = hsv255.h / 360.0f; 68 | hsv->s = hsv255.s / 255.0f; 69 | hsv->v = hsv255.v / 255.0f; 70 | } 71 | 72 | 73 | void RGBColorFromHSVColor(const HRHSVColor* hsv,HRRGBColor* rgb){ 74 | /* 75 | UIColorには 76 | [UIColor colorWithHue:<#(CGFloat)#> saturation:<#(CGFloat)#> brightness:<#(CGFloat)#> alpha:<#(CGFloat)#>] 77 | もあります 78 | */ 79 | if(hsv->s == 0.0f) 80 | { 81 | rgb->r = rgb->g = rgb->b = hsv->v; 82 | return; 83 | } 84 | 85 | float h360 = hsv->h * 360.0f; 86 | int i; 87 | float f; 88 | float m; 89 | float n; 90 | float k; 91 | 92 | i = floor(h360 /60); 93 | if(i < 0){ 94 | i *= -1; 95 | } 96 | f = h360 / 60.0f - i; 97 | m = hsv->v * (1 - hsv->s); 98 | n = hsv->v * (1 - f * hsv->s); 99 | k = hsv->v * (1 - (1 - f) * hsv->s); 100 | 101 | switch (i) { 102 | case 0:{ 103 | rgb->r = hsv->v; 104 | rgb->g = k; 105 | rgb->b = m; 106 | break; 107 | } 108 | case 1:{ 109 | rgb->r = n; 110 | rgb->g = hsv->v; 111 | rgb->b = m; 112 | break; 113 | } 114 | case 2:{ 115 | rgb->r = m; 116 | rgb->g = hsv->v; 117 | rgb->b = k; 118 | break; 119 | } 120 | case 3:{ 121 | rgb->r = m; 122 | rgb->g = n; 123 | rgb->b = hsv->v; 124 | break; 125 | } 126 | case 4:{ 127 | rgb->r = k; 128 | rgb->g = m; 129 | rgb->b = hsv->v; 130 | break; 131 | } 132 | case 5:{ 133 | rgb->r = hsv->v; 134 | rgb->g = m; 135 | rgb->b = n; 136 | break; 137 | } 138 | default: 139 | break; 140 | } 141 | } 142 | 143 | void RGBColorFromUIColor(const UIColor* uiColor,HRRGBColor* rgb){ 144 | const CGFloat* components = CGColorGetComponents(uiColor.CGColor); 145 | if(CGColorGetNumberOfComponents(uiColor.CGColor) == 2){ 146 | rgb->r = components[0]; 147 | rgb->g = components[0]; 148 | rgb->b = components[0]; 149 | }else{ 150 | rgb->r = components[0]; 151 | rgb->g = components[1]; 152 | rgb->b = components[2]; 153 | } 154 | } 155 | 156 | int HexColorFromRGBColor(const HRRGBColor* rgb){ 157 | return (int)(rgb->r*255.0f) << 16 | (int)(rgb->g*255.0f) << 8 | (int)(rgb->b*255.0f) << 0; 158 | } 159 | 160 | int HexColorFromUIColor(const UIColor* color){ 161 | HRRGBColor rgb_color; 162 | RGBColorFromUIColor(color, &rgb_color); 163 | return HexColorFromRGBColor(&rgb_color); 164 | } 165 | 166 | bool HRHSVColorEqualToColor(const HRHSVColor* hsv1,const HRHSVColor* hsv2){ 167 | return (hsv1->h == hsv2->h) && (hsv1->s == hsv2->s) && (hsv1->v == hsv2->v); 168 | } 169 | 170 | void HSVColorAt(HRHSVColor* hsv,float x,float y,float saturationUpperLimit,float brightness){ 171 | hsv->h = x; 172 | hsv->s = 1.0f - (y * saturationUpperLimit); 173 | hsv->v = brightness; 174 | } -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRColorPickerViewController.m: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2011 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #import "HRColorPickerViewController.h" 29 | #import "HRColorPickerView.h" 30 | 31 | @implementation HRColorPickerViewController 32 | 33 | @synthesize delegate; 34 | 35 | 36 | + (HRColorPickerViewController *)colorPickerViewControllerWithColor:(UIColor *)color 37 | { 38 | return [[HRColorPickerViewController alloc] initWithColor:color fullColor:NO saveStyle:HCPCSaveStyleSaveAlways]; 39 | } 40 | 41 | + (HRColorPickerViewController *)cancelableColorPickerViewControllerWithColor:(UIColor *)color 42 | { 43 | return [[HRColorPickerViewController alloc] initWithColor:color fullColor:NO saveStyle:HCPCSaveStyleSaveAndCancel]; 44 | } 45 | 46 | + (HRColorPickerViewController *)fullColorPickerViewControllerWithColor:(UIColor *)color 47 | { 48 | return [[HRColorPickerViewController alloc] initWithColor:color fullColor:YES saveStyle:HCPCSaveStyleSaveAlways]; 49 | } 50 | 51 | + (HRColorPickerViewController *)cancelableFullColorPickerViewControllerWithColor:(UIColor *)color 52 | { 53 | return [[HRColorPickerViewController alloc] initWithColor:color fullColor:YES saveStyle:HCPCSaveStyleSaveAndCancel]; 54 | } 55 | 56 | 57 | 58 | - (id)initWithDefaultColor:(UIColor *)defaultColor 59 | { 60 | return [self initWithColor:defaultColor fullColor:NO saveStyle:HCPCSaveStyleSaveAlways]; 61 | } 62 | 63 | - (id)initWithColor:(UIColor*)defaultColor fullColor:(BOOL)fullColor saveStyle:(HCPCSaveStyle)saveStyle 64 | 65 | { 66 | self = [super initWithNibName:nil bundle:nil]; 67 | if (self) { 68 | _color = defaultColor; 69 | _fullColor = fullColor; 70 | _saveStyle = saveStyle; 71 | } 72 | return self; 73 | } 74 | 75 | - (void)loadView 76 | { 77 | CGRect frame = [[UIScreen mainScreen] applicationFrame]; 78 | frame.size.height -= 44.f; 79 | 80 | self.view = [[UIView alloc] initWithFrame:frame]; 81 | 82 | HRRGBColor rgbColor; 83 | RGBColorFromUIColor(_color, &rgbColor); 84 | 85 | HRColorPickerStyle style; 86 | 87 | // j5136p1 12/08/2014 : Set size to mainScreen size and if a navigationviewcontroller exists we change it to navigation controller view size 88 | CGSize viewSize = [[UIScreen mainScreen] applicationFrame].size; 89 | 90 | // j5136p1 12/08/2014 : if a navigationviewcontroller exists we change it to navigation controller view size to fit ex. modal views 91 | if (self.navigationController) 92 | viewSize = CGSizeMake(self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height); 93 | 94 | if (_fullColor) { 95 | style = [HRColorPickerView fitScreenFullColorStyleWithSize:viewSize]; 96 | }else{ 97 | style = [HRColorPickerView fitScreenStyleWithSize:viewSize]; 98 | } 99 | 100 | colorPickerView = [[HRColorPickerView alloc] initWithStyle:style defaultColor:rgbColor]; 101 | 102 | [self.view addSubview:colorPickerView]; 103 | 104 | if (_saveStyle == HCPCSaveStyleSaveAndCancel) { 105 | UIBarButtonItem *buttonItem; 106 | 107 | buttonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel:)]; 108 | self.navigationItem.leftBarButtonItem = buttonItem; 109 | 110 | buttonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(save:)]; 111 | self.navigationItem.rightBarButtonItem = buttonItem; 112 | } 113 | } 114 | 115 | - (void)viewDidLoad 116 | { 117 | [super viewDidLoad]; 118 | } 119 | 120 | - (void)viewWillDisappear:(BOOL)animated 121 | { 122 | [super viewWillDisappear:animated]; 123 | 124 | if (_saveStyle == HCPCSaveStyleSaveAlways) { 125 | [self save:self]; 126 | } 127 | } 128 | 129 | - (void)saveColor:(id)sender{ 130 | [self save]; 131 | } 132 | 133 | - (void)save 134 | { 135 | if (self.delegate) { 136 | HRRGBColor rgbColor = [colorPickerView RGBColor]; 137 | [self.delegate setSelectedColor:[UIColor colorWithRed:rgbColor.r green:rgbColor.g blue:rgbColor.b alpha:1.0f] tag:self.tag]; 138 | } 139 | [self.navigationController popViewControllerAnimated:YES]; 140 | } 141 | 142 | - (void)save:(id)sender 143 | { 144 | [self save]; 145 | } 146 | 147 | - (void)cancel:(id)sender 148 | { 149 | [self.navigationController popViewControllerAnimated:YES]; 150 | } 151 | 152 | 153 | - (void)didReceiveMemoryWarning 154 | { 155 | // Releases the view if it doesn't have a superview. 156 | [super didReceiveMemoryWarning]; 157 | // Release any cached data, images, etc that aren't in use. 158 | } 159 | 160 | 161 | #pragma mark - View lifecycle 162 | 163 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations { 164 | return UIInterfaceOrientationMaskPortrait; 165 | } 166 | 167 | @end 168 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/ZSSFontsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSFontsViewController.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Will Swan on 03/09/2016. 6 | // Copyright © 2016 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSFontsViewController.h" 10 | 11 | @interface ZSSFontsViewController () { 12 | 13 | ZSSFontFamily selectedFontFamily; 14 | 15 | } 16 | 17 | @end 18 | 19 | @implementation ZSSFontsViewController 20 | 21 | @synthesize delegate; 22 | 23 | #pragma mark - Init Section 24 | + (ZSSFontsViewController *)cancelableFontPickerViewControllerWithFontFamily:(ZSSFontFamily)fontFamily { 25 | return [[ZSSFontsViewController alloc] initWithFontFamily:fontFamily]; 26 | } 27 | 28 | - (id)initWithFontFamily:(ZSSFontFamily)fontFamily { 29 | 30 | self = [super initWithNibName:nil bundle:nil]; 31 | if (self) { 32 | _font = fontFamily; 33 | } 34 | return self; 35 | 36 | } 37 | 38 | #pragma mark - View Did Load Section 39 | - (void)viewDidLoad { 40 | 41 | [super viewDidLoad]; 42 | 43 | //Set up navigation 44 | [self setUpNavigation]; 45 | 46 | //Create table view 47 | [self createTableView]; 48 | 49 | } 50 | 51 | #pragma mark - Set Up View Section 52 | 53 | - (void)setUpNavigation { 54 | 55 | self.navigationItem.title = @"Fonts"; 56 | 57 | UIBarButtonItem *buttonItem; 58 | 59 | buttonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel:)]; 60 | self.navigationItem.leftBarButtonItem = buttonItem; 61 | 62 | buttonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(save:)]; 63 | self.navigationItem.rightBarButtonItem = buttonItem; 64 | 65 | } 66 | 67 | - (void)createTableView { 68 | 69 | UITableView *tableView = [[UITableView alloc] init]; 70 | tableView.frame = CGRectMake(0.0f, 0.0f, self.view.frame.size.width, self.view.frame.size.height - self.navigationController.navigationBar.frame.size.height); 71 | tableView.delegate = self; 72 | tableView.dataSource = self; 73 | tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; 74 | 75 | [self.view addSubview:tableView]; 76 | 77 | } 78 | 79 | #pragma mark - Table View Section 80 | 81 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 82 | return 1; 83 | } 84 | 85 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 86 | 87 | return 7; 88 | 89 | } 90 | 91 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 92 | 93 | static NSString *CellIdentifier = @"fontCell"; 94 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 95 | 96 | if (cell == nil) { 97 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 98 | } 99 | 100 | float fontSize = 20.0f; 101 | 102 | switch (indexPath.row) { 103 | case 0: 104 | cell.textLabel.text = @"Default"; 105 | cell.textLabel.font = [UIFont fontWithName:@"ArialMT" size:fontSize]; 106 | break; 107 | 108 | case 1: 109 | cell.textLabel.text = @"Trebuchet"; 110 | cell.textLabel.font = [UIFont fontWithName:@"TrebuchetMS" size:fontSize]; 111 | break; 112 | 113 | case 2: 114 | cell.textLabel.text = @"Verdana"; 115 | cell.textLabel.font = [UIFont fontWithName:@"Verdana" size:fontSize]; 116 | break; 117 | 118 | case 3: 119 | cell.textLabel.text = @"Georgia"; 120 | cell.textLabel.font = [UIFont fontWithName:@"Georgia" size:fontSize]; 121 | break; 122 | 123 | case 4: 124 | cell.textLabel.text = @"Palatino"; 125 | cell.textLabel.font = [UIFont fontWithName:@"Palatino-Roman" size:fontSize]; 126 | break; 127 | 128 | case 5: 129 | cell.textLabel.text = @"Times New Roman"; 130 | cell.textLabel.font = [UIFont fontWithName:@"TimesNewRomanPSMT" size:fontSize]; 131 | break; 132 | 133 | case 6: 134 | cell.textLabel.text = @"Courier New"; 135 | cell.textLabel.font = [UIFont fontWithName:@"CourierNewPSMT" size:fontSize]; 136 | break; 137 | 138 | default: 139 | break; 140 | } 141 | 142 | 143 | cell.selectionStyle = UITableViewCellSelectionStyleBlue; 144 | 145 | return cell; 146 | 147 | } 148 | 149 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 150 | 151 | 152 | switch (indexPath.row) { 153 | case 0: 154 | selectedFontFamily = ZSSFontFamilyDefault; 155 | break; 156 | 157 | case 1: 158 | selectedFontFamily = ZSSFontFamilyTrebuchet; 159 | break; 160 | 161 | case 2: 162 | selectedFontFamily = ZSSFontFamilyVerdana; 163 | break; 164 | 165 | case 3: 166 | selectedFontFamily = ZSSFontFamilyGeorgia; 167 | break; 168 | 169 | case 4: 170 | selectedFontFamily = ZSSFontFamilyPalatino; 171 | break; 172 | 173 | case 5: 174 | selectedFontFamily = ZSSFontFamilyTimesNew; 175 | break; 176 | 177 | case 6: 178 | selectedFontFamily = ZSSFontFamilyCourierNew; 179 | break; 180 | 181 | default: 182 | break; 183 | } 184 | 185 | } 186 | 187 | #pragma mark - Navigation Item Interactions Section 188 | 189 | - (void)save { 190 | 191 | if (self.delegate) { 192 | //HRRGBColor rgbColor = [colorPickerView RGBColor]; 193 | [self.delegate setSelectedFontFamily:selectedFontFamily]; 194 | } 195 | 196 | [self.navigationController popViewControllerAnimated:YES]; 197 | 198 | } 199 | 200 | - (void)save:(id)sender { 201 | [self save]; 202 | } 203 | 204 | - (void)cancel:(id)sender { 205 | [self.navigationController popViewControllerAnimated:YES]; 206 | } 207 | 208 | #pragma mark - Memory Warning Section 209 | - (void)didReceiveMemoryWarning { 210 | [super didReceiveMemoryWarning]; 211 | } 212 | 213 | @end 214 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/CYRTextStorage.m: -------------------------------------------------------------------------------- 1 | // 2 | // CYRTextStorage.m 3 | // 4 | // Version 0.2.0 5 | // 6 | // Created by Illya Busigin on 01/05/2014. 7 | // Copyright (c) 2014 Cyrillian, Inc. 8 | // 9 | // Distributed under MIT license. 10 | // Get the latest version from here: 11 | // 12 | // https://github.com/illyabusigin/CYRTextView 13 | // 14 | // The MIT License (MIT) 15 | // 16 | // Copyright (c) 2014 Cyrillian, Inc. 17 | // 18 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 19 | // this software and associated documentation files (the "Software"), to deal in 20 | // the Software without restriction, including without limitation the rights to 21 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 22 | // the Software, and to permit persons to whom the Software is furnished to do so, 23 | // subject to the following conditions: 24 | // 25 | // The above copyright notice and this permission notice shall be included in all 26 | // copies or substantial portions of the Software. 27 | // 28 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 30 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 31 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 32 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 33 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 34 | 35 | #import "CYRTextStorage.h" 36 | #import "CYRToken.h" 37 | 38 | @interface CYRTextStorage () 39 | 40 | @property (nonatomic, strong) NSMutableAttributedString *attributedString; 41 | @property (nonatomic, strong) NSMutableDictionary *regularExpressionCache; 42 | 43 | @end 44 | 45 | @implementation CYRTextStorage 46 | 47 | #pragma mark - Initialization & Setup 48 | 49 | - (id)init 50 | { 51 | if (self = [super init]) 52 | { 53 | _defaultFont = [UIFont systemFontOfSize:12.0f]; 54 | _attributedString = [NSMutableAttributedString new]; 55 | 56 | _tokens = @[]; 57 | _regularExpressionCache = @{}.mutableCopy; 58 | } 59 | 60 | return self; 61 | } 62 | 63 | 64 | #pragma mark - Overrides 65 | 66 | - (void)setTokens:(NSMutableArray *)tokens 67 | { 68 | _tokens = tokens; 69 | 70 | // Clear the regular expression cache 71 | [self.regularExpressionCache removeAllObjects]; 72 | 73 | // Redraw all text 74 | [self update]; 75 | } 76 | 77 | - (NSString *)string 78 | { 79 | return [_attributedString string]; 80 | } 81 | 82 | - (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range 83 | { 84 | return [_attributedString attributesAtIndex:location effectiveRange:range]; 85 | } 86 | 87 | - (void)replaceCharactersInRange:(NSRange)range withString:(NSString*)str 88 | { 89 | [self beginEditing]; 90 | 91 | [_attributedString replaceCharactersInRange:range withString:str]; 92 | 93 | [self edited:NSTextStorageEditedCharacters | NSTextStorageEditedAttributes range:range changeInLength:str.length - range.length]; 94 | [self endEditing]; 95 | } 96 | 97 | - (void)setAttributes:(NSDictionary*)attrs range:(NSRange)range 98 | { 99 | [self beginEditing]; 100 | 101 | [_attributedString setAttributes:attrs range:range]; 102 | 103 | [self edited:NSTextStorageEditedAttributes range:range changeInLength:0]; 104 | [self endEditing]; 105 | } 106 | 107 | -(void)processEditing 108 | { 109 | [self performReplacementsForRange:[self editedRange]]; 110 | [super processEditing]; 111 | } 112 | 113 | - (void)performReplacementsForRange:(NSRange)changedRange 114 | { 115 | NSRange extendedRange = NSUnionRange(changedRange, [[_attributedString string] lineRangeForRange:NSMakeRange(NSMaxRange(changedRange), 0)]); 116 | 117 | [self applyStylesToRange:extendedRange]; 118 | } 119 | 120 | 121 | -(void)update 122 | { 123 | [self addAttributes:@{NSFontAttributeName : self.defaultFont} range:NSMakeRange(0, self.length)]; 124 | 125 | [self applyStylesToRange:NSMakeRange(0, self.length)]; 126 | } 127 | 128 | - (void)applyStylesToRange:(NSRange)searchRange 129 | { 130 | if (self.editedRange.location == NSNotFound) 131 | { 132 | return; 133 | } 134 | 135 | NSRange paragaphRange = [self.string paragraphRangeForRange: self.editedRange]; 136 | 137 | // Reset the text attributes 138 | [self setAttributes:@{NSForegroundColorAttributeName : [UIColor blackColor]} range:paragaphRange]; 139 | 140 | [self setAttributes:@{NSFontAttributeName : self.defaultFont} range:paragaphRange]; 141 | 142 | for (CYRToken *attribute in self.tokens) 143 | { 144 | NSRegularExpression *regex = [self expressionForDefinition:attribute.name]; 145 | [regex enumerateMatchesInString:self.string options:0 range:paragaphRange 146 | usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { 147 | 148 | [attribute.attributes enumerateKeysAndObjectsUsingBlock:^(NSString *attributeName, id attributeValue, BOOL *stop) { 149 | [self addAttribute:attributeName value:attributeValue range:result.range]; 150 | }]; 151 | }]; 152 | } 153 | } 154 | 155 | - (NSRegularExpression *)expressionForDefinition:(NSString *)definition 156 | { 157 | __block CYRToken *attribute = nil; 158 | 159 | [self.tokens enumerateObjectsUsingBlock:^(CYRToken *enumeratedAttribute, NSUInteger idx, BOOL *stop) { 160 | if ([enumeratedAttribute.name isEqualToString:definition]) 161 | { 162 | attribute = enumeratedAttribute; 163 | *stop = YES; 164 | } 165 | }]; 166 | 167 | NSRegularExpression *expression = self.regularExpressionCache[attribute.expression]; 168 | 169 | if (!expression) 170 | { 171 | expression = [NSRegularExpression regularExpressionWithPattern:attribute.expression 172 | options:NSRegularExpressionCaseInsensitive error:nil]; 173 | 174 | [self.regularExpressionCache setObject:expression forKey:definition]; 175 | } 176 | 177 | return expression; 178 | } 179 | 180 | @end 181 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ######################### 2 | # .gitignore file for Xcode4 and Xcode5 Source projects 3 | # 4 | # Apple bugs, waiting for Apple to fix/respond: 5 | # 6 | # 15564624 - what does the xccheckout file in Xcode5 do? Where's the documentation? 7 | # 8 | # Version 2.3 9 | # For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects 10 | # 11 | # 2014 updates: 12 | # - appended non-standard items DISABLED by default (uncomment if you use those tools) 13 | # - removed the edit that an SO.com moderator made without bothering to ask me 14 | # - researched CocoaPods .lock more carefully, thanks to Gokhan Celiker 15 | # 2013 updates: 16 | # - fixed the broken "save personal Schemes" 17 | # - added line-by-line explanations for EVERYTHING (some were missing) 18 | # 19 | # NB: if you are storing "built" products, this WILL NOT WORK, 20 | # and you should use a different .gitignore (or none at all) 21 | # This file is for SOURCE projects, where there are many extra 22 | # files that we want to exclude 23 | # 24 | ######################### 25 | 26 | ##### 27 | # OS X temporary files that should never be committed 28 | # 29 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html 30 | 31 | .DS_Store 32 | 33 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html 34 | 35 | .Trashes 36 | 37 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html 38 | 39 | *.swp 40 | 41 | # 42 | # *.lock - this is used and abused by many editors for many different things. 43 | # For the main ones I use (e.g. Eclipse), it should be excluded 44 | # from source-control, but YMMV. 45 | # (lock files are usually local-only file-synchronization on the local FS that should NOT go in git) 46 | # c.f. the "OPTIONAL" section at bottom though, for tool-specific variations! 47 | 48 | *.lock 49 | 50 | 51 | # 52 | # profile - REMOVED temporarily (on double-checking, I can't find it in OS X docs?) 53 | #profile 54 | 55 | 56 | #### 57 | # Xcode temporary files that should never be committed 58 | # 59 | # NB: NIB/XIB files still exist even on Storyboard projects, so we want this... 60 | 61 | *~.nib 62 | 63 | 64 | #### 65 | # Xcode build files - 66 | # 67 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" 68 | 69 | DerivedData/ 70 | 71 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" 72 | 73 | build/ 74 | 75 | 76 | ##### 77 | # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) 78 | # 79 | # This is complicated: 80 | # 81 | # SOMETIMES you need to put this file in version control. 82 | # Apple designed it poorly - if you use "custom executables", they are 83 | # saved in this file. 84 | # 99% of projects do NOT use those, so they do NOT want to version control this file. 85 | # ..but if you're in the 1%, comment out the line "*.pbxuser" 86 | 87 | # .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html 88 | 89 | *.pbxuser 90 | 91 | # .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html 92 | 93 | *.mode1v3 94 | 95 | # .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html 96 | 97 | *.mode2v3 98 | 99 | # .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file 100 | 101 | *.perspectivev3 102 | 103 | # NB: also, whitelist the default ones, some projects need to use these 104 | !default.pbxuser 105 | !default.mode1v3 106 | !default.mode2v3 107 | !default.perspectivev3 108 | 109 | 110 | #### 111 | # Xcode 4 - semi-personal settings 112 | # 113 | # 114 | # OPTION 1: --------------------------------- 115 | # throw away ALL personal settings (including custom schemes! 116 | # - unless they are "shared") 117 | # 118 | # NB: this is exclusive with OPTION 2 below 119 | xcuserdata 120 | 121 | # OPTION 2: --------------------------------- 122 | # get rid of ALL personal settings, but KEEP SOME OF THEM 123 | # - NB: you must manually uncomment the bits you want to keep 124 | # 125 | # NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X, 126 | # or manually install git over the top of the OS X version 127 | # NB: this is exclusive with OPTION 1 above 128 | # 129 | #xcuserdata/**/* 130 | 131 | # (requires option 2 above): Personal Schemes 132 | # 133 | #!xcuserdata/**/xcschemes/* 134 | 135 | #### 136 | # XCode 4 workspaces - more detailed 137 | # 138 | # Workspaces are important! They are a core feature of Xcode - don't exclude them :) 139 | # 140 | # Workspace layout is quite spammy. For reference: 141 | # 142 | # /(root)/ 143 | # /(project-name).xcodeproj/ 144 | # project.pbxproj 145 | # /project.xcworkspace/ 146 | # contents.xcworkspacedata 147 | # /xcuserdata/ 148 | # /(your name)/xcuserdatad/ 149 | # UserInterfaceState.xcuserstate 150 | # /xcsshareddata/ 151 | # /xcschemes/ 152 | # (shared scheme name).xcscheme 153 | # /xcuserdata/ 154 | # /(your name)/xcuserdatad/ 155 | # (private scheme).xcscheme 156 | # xcschememanagement.plist 157 | # 158 | # 159 | 160 | #### 161 | # Xcode 4 - Deprecated classes 162 | # 163 | # Allegedly, if you manually "deprecate" your classes, they get moved here. 164 | # 165 | # We're using source-control, so this is a "feature" that we do not want! 166 | 167 | *.moved-aside 168 | 169 | #### 170 | # OPTIONAL: Some well-known tools that people use side-by-side with Xcode / iOS development 171 | # 172 | # NB: I'd rather not include these here, but gitignore's design is weak and doesn't allow 173 | # modular gitignore: you have to put EVERYTHING in one file. 174 | # 175 | # COCOAPODS: 176 | # 177 | # c.f. http://guides.cocoapods.org/using/using-cocoapods.html#what-is-a-podfilelock 178 | # c.f. http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 179 | # 180 | #!Podfile.lock 181 | # 182 | # RUBY: 183 | # 184 | # c.f. http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/ 185 | # 186 | #!Gemfile.lock 187 | # 188 | # IDEA: 189 | # 190 | #.idea 191 | # 192 | # TEXTMATE: 193 | # 194 | # -- UNVERIFIED: c.f. http://stackoverflow.com/a/50283/153422 195 | # 196 | #tm_build_errors 197 | 198 | #### 199 | # UNKNOWN: recommended by others, but I can't discover what these files are 200 | # 201 | # Community suggestions (unverified, no evidence available - DISABLED by default) 202 | # 203 | # 1. Xcode 5 - VCS file 204 | # 205 | # "The data in this file not represent state of your project. 206 | # If you'll leave this file in git - you will have merge conflicts during 207 | # pull your cahnges to other's repo" 208 | # 209 | #*.xccheckout 210 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ZSSRichTextEditor 2 | ============= 3 | 4 | The Editor 5 | --- 6 | 7 | `ZSSRichTextEditor` is a beautiful Rich Text `WYSIWYG Editor` for `iOS`. It includes all of the standard editor tools one would expect from a `WYSIWYG` editor as well as an amazing source view with syntax highlighting. 8 | 9 | ![toolbar](https://user-images.githubusercontent.com/30858/132384030-59c0d2be-ab90-4535-9dd8-e5ee3e405e2e.gif) 10 | 11 | The editor is used how any other text input area in iOS is used. A selection of text or content is made, then tapping on the toolbar item below will apply that style. A Source View is also included, you can make changes and this will be reflected in the editor preview. 12 | 13 | ![editor](https://user-images.githubusercontent.com/30858/132384094-9a1d2182-0c21-468d-b3d9-2049397e2af5.gif) 14 | 15 | Colors 16 | --- 17 | 18 | We wanted to have a really beautiful color picker to make changing colors really simple. So, we used the open-source HRColorPicker which was exactly what we were looking for. Choosing colors for text or background is simple and seamless. 19 | 20 | ![colors](https://user-images.githubusercontent.com/30858/132384119-6b4a836d-1c21-400a-bb5a-5d18534d3bd5.gif) 21 | 22 | How It Works 23 | --- 24 | 25 | Just subclass `ZSSRichTextEditor` and use the following: 26 | 27 | ```objective-c 28 | // HTML Content to set in the editor 29 | NSString *html = @"" 30 | "

This is a test of the ZSSRichTextEditor by Zed Said Studio

"; 31 | 32 | // Set the base URL if you would like to use relative links, such as to images. 33 | self.baseURL = [NSURL URLWithString:@"http://www.zedsaid.com"]; 34 | 35 | // If you want to pretty print HTML within the source view. 36 | self.formatHTML = YES; 37 | 38 | // set the initial HTML for the editor 39 | [self setHTML:html]; 40 | ``` 41 | 42 | If you want to retrieve the HTML from the editor: 43 | ```objective-c 44 | // Returns an NSString 45 | [self getHTML]; 46 | ``` 47 | 48 | Insert HTML at the current caret position: 49 | ```objective-c 50 | NSString *html = @"I love cats!"; 51 | [self insertHTML:html]; 52 | ``` 53 | 54 | Change the tint color of the toolbar buttons: 55 | ```objective-c 56 | // Set the toolbar item color 57 | self.toolbarItemTintColor = [UIColor greenColor]; 58 | 59 | // Set the toolbar selected color 60 | self.toolbarItemSelectedTintColor = [UIColor redColor]; 61 | ``` 62 | 63 | Show only specified buttons in the toolbar: 64 | ```objective-c 65 | self.enabledToolbarItems = @[ZSSRichTextEditorToolbarBold, ZSSRichTextEditorToolbarH1, ZSSRichTextEditorToolbarParagraph]; 66 | ``` 67 | 68 | Always show the toolbar even when the keyboard is hidden: 69 | ```objective-c 70 | self.alwaysShowToolbar = YES; 71 | ``` 72 | 73 | Set A Placeholder 74 | --- 75 | 76 | ```objective-c 77 | [self setPlaceholder:@"This is a placeholder that will show when there is no content(html)"]; 78 | 79 | ``` 80 | 81 | Insert Link and Insert Image 82 | --- 83 | 84 | If you want to manually insert a link or image where the cursor is, you can use the following methods: 85 | 86 | **Insert Image** 87 | ```objective-c 88 | - (void)insertImage:(NSString *)url alt:(NSString *)alt; 89 | ``` 90 | 91 | **Insert Link** 92 | ```objective-c 93 | - (void)insertLink:(NSString *)url title:(NSString *)title; 94 | ``` 95 | 96 | Custom Pickers 97 | --- 98 | 99 | You can implement your own pickers for images and links if you have an alternate method that you are wanting to use. E.g., uploading an image from your camera roll then inserting the URL. 100 | 101 | When the alternate picker icon (crosshair) is tapped it will call the corresponding method, which you need to override in your `ZSSRichTextEditor` subclass (see example project): 102 | 103 | ```objective-c 104 | - (void)showInsertURLAlternatePicker { 105 | 106 | [self dismissAlertView]; 107 | 108 | // Show your custom picker 109 | 110 | } 111 | 112 | 113 | - (void)showInsertImageAlternatePicker { 114 | 115 | [self dismissAlertView]; 116 | 117 | // Show your custom picker 118 | 119 | } 120 | ``` 121 | 122 | Custom Toolbar Buttons 123 | --- 124 | 125 | ```objective-c 126 | UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, buttonWidth, 28.0f)]; 127 | [myButton setTitle:@"My Button" forState:UIControlStateNormal]; 128 | [myButton addTarget:self 129 | action:@selector(didTapCustomToolbarButton:) 130 | forControlEvents:UIControlEventTouchUpInside]; 131 | 132 | [self addCustomToolbarItemWithButton:myButton]; 133 | 134 | ``` 135 | 136 | Custom CSS 137 | --- 138 | 139 | ```objective-c 140 | NSString *customCSS = @"a {text-decoration:none;} a:hover {color:#FF0000;}"; 141 | [self setCSS:customCSS]; 142 | 143 | ``` 144 | 145 | Receive Editor Did Change Events 146 | --- 147 | 148 | Add the following to your viewDidLoad method: 149 | 150 | ```objective-c 151 | self.receiveEditorDidChangeEvents = YES; 152 | ``` 153 | 154 | Then you will receive events in the following method: 155 | 156 | ```objective-c 157 | - (void)editorDidChangeWithText:(NSString *)text andHTML:(NSString *)html { 158 | 159 | NSLog(@"Text Has Changed: %@", text); 160 | 161 | NSLog(@"HTML Has Changed: %@", html); 162 | 163 | } 164 | ``` 165 | 166 | Receive Hashtag & Mention Events 167 | --- 168 | 169 | Hashtags: 170 | ```objective-c 171 | - (void)hashtagRecognizedWithWord:(NSString *)word { 172 | 173 | NSLog(@"Hashtag has been recognized: %@", word); 174 | 175 | } 176 | ``` 177 | Mentions: 178 | ```objective-c 179 | - (void)mentionRecognizedWithWord:(NSString *)word { 180 | 181 | NSLog(@"Mention has been recognized: %@", word); 182 | 183 | } 184 | ``` 185 | 186 | Supported Functions 187 | --- 188 | 189 | ZSSRichTextEditor has the following functions: 190 | 191 | * Bold 192 | * Italic 193 | * Subscript 194 | * Superscript 195 | * Strikethrough 196 | * Underline 197 | * Remove Formatting 198 | * Font 199 | * Justify Left 200 | * Justify Center 201 | * Justify Right 202 | * Justify Full 203 | * Paragraph 204 | * Heading 1 205 | * Heading 2 206 | * Heading 3 207 | * Heading 4 208 | * Heading 5 209 | * Heading 6 210 | * Undo 211 | * Redo 212 | * Unordered List 213 | * Ordered List 214 | * Indent 215 | * Outdent 216 | * Insert Image 217 | * Insert Link 218 | * Quick Link 219 | * Unlink 220 | * Horizontal Rule 221 | * View Source 222 | * Text Color 223 | * Background Color 224 | 225 | Installation 226 | -------------- 227 | You can use `CocoaPods` or manually using the following instructions: 228 | 229 | `ZSSRichTextEditor` requires iOS7 as well as `CoreGraphics.framework` and `CoreText.framework`. 230 | 231 | - Copy the `Source` folder to your project. 232 | - Subclass `ZSSRichTextEditor` and implement the methods as mentioned above. 233 | 234 | **When using `ZSSRichTextEditor` in your own project, XCode will automatically add `ZSSRichTextEditor.js` to compile sources under build phases, this will cause `ZSSRichTextEditor` to not work correctly as the javascript file won't be included in your app. Instead, remove it from compile sources and add it to copy bundle resources.** 235 | 236 | Attribution 237 | -------------- 238 | 239 | `ZSSRichTextEditor` uses portions of code from the following sources: 240 | 241 | | Component | Description | License | 242 | | :------------- |:-------------| :-----| 243 | | [CYRTextView](https://github.com/illyabusigin/CYRTextView) | CYRTextView is a UITextView subclass that implements a variety of features that are relevant to a syntax or code text view. | [MIT](https://github.com/illyabusigin/CYRTextView/blob/master/LICENSE) | 244 | | [HRColorPicker](https://github.com/hayashi311/Color-Picker-for-iOS) | Simple color picker for iPhone | [BSD](https://github.com/hayashi311/Color-Picker-for-iOS/blob/master/ColorPicker/HRColorPickerView.h) | 245 | | [jQuery](https://jquery.com) | jQuery is a fast, small, and feature-rich JavaScript library. | [MIT](http://jquery.org/license) | 246 | | [JS Beautifier](https://github.com/einars/js-beautify) | Makes ugly Javascript pretty | [MIT](https://github.com/einars/js-beautify/blob/master/LICENSE) | 247 | 248 | Contact 249 | -------------- 250 | Visit us online at [http://www.zedsaid.com](http://www.zedsaid.com) or [@zedsaid](https://twitter.com/zedsaid). 251 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/ZSSTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSTextView.m 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 1/29/14. 6 | // Copyright (c) 2014 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import "ZSSTextView.h" 10 | #import 11 | 12 | #define RGB(r,g,b) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:1.0f] 13 | 14 | @implementation ZSSTextView 15 | 16 | - (id)initWithFrame:(CGRect)frame 17 | { 18 | self = [super initWithFrame:frame]; 19 | if (self) { 20 | [self commonSetup]; 21 | } 22 | return self; 23 | } 24 | 25 | - (void)commonSetup 26 | { 27 | _defaultFont = [UIFont systemFontOfSize:14.0f]; 28 | _boldFont = [UIFont boldSystemFontOfSize:14.0f]; 29 | _italicFont = [UIFont fontWithName:@"HelveticaNeue-Oblique" size:14.0f]; 30 | 31 | self.font = _defaultFont; 32 | 33 | [self addObserver:self forKeyPath:NSStringFromSelector(@selector(defaultFont)) options:NSKeyValueObservingOptionNew context:0]; 34 | [self addObserver:self forKeyPath:NSStringFromSelector(@selector(boldFont)) options:NSKeyValueObservingOptionNew context:0]; 35 | [self addObserver:self forKeyPath:NSStringFromSelector(@selector(italicFont)) options:NSKeyValueObservingOptionNew context:0]; 36 | 37 | if (_italicFont == nil && ([UIFontDescriptor class] != nil)) 38 | { 39 | // This works around a bug in 7.0.3 where HelveticaNeue-Italic is not present as a UIFont option 40 | _italicFont = (__bridge_transfer UIFont*)CTFontCreateWithName(CFSTR("HelveticaNeue-Italic"), 14.0f, NULL); 41 | } 42 | 43 | self.tokens = [self solverTokens]; 44 | } 45 | 46 | - (NSArray *)solverTokens 47 | { 48 | NSArray *solverTokens = @[ 49 | [CYRToken tokenWithName:@"html_tags" 50 | expression:@"(<\\/?[a-z][^<>]*>)" 51 | attributes:@{ 52 | NSForegroundColorAttributeName : RGB(25, 0, 151)}], 53 | [CYRToken tokenWithName:@"a_tag" 54 | expression:@"(<\\/?[a][^<>]*>)" 55 | attributes:@{ 56 | NSForegroundColorAttributeName : RGB(24, 104, 10)}], 57 | [CYRToken tokenWithName:@"img_tag" 58 | expression:@"(<\\/?[img][^<>]*>)" 59 | attributes:@{ 60 | NSForegroundColorAttributeName : RGB(148, 0, 151)}], 61 | [CYRToken tokenWithName:@"html_entities" 62 | expression:@"("|&|'|<|>| |¡|¢|£|¤|¥|¦|§|¨|©|ª|«|¬|­|®|¯|°|±|²|³|´|µ|¶|·|¸|¹|º|»|¼|½|¾|¿|À|Á|Â|Ã|Ä|Å|Æ|Ç|È|É|Ê|Ë|Ì|Í|Î|Ï|Ð|Ñ|Ò|Ó|Ô|Õ|Ö|×|Ø|Ù|Ú|Û|Ü|Ý|Þ|ß|à|á|â|ã|ä|å|æ|ç|è|é|ê|ë|ì|í|î|ï|ð|ñ|ò|ó|ô|õ|ö|÷|ø|ù|ú|û|ü|ý|þ|ÿ|Œ|œ|Š|š|Ÿ|ƒ|ˆ|˜|Α|Β|Γ|Δ|Ε|Ζ|Η|Θ|Ι|Κ|Λ|Μ|Ν|Ξ|Ο|Π|Ρ|Σ|Τ|Υ|Φ|Χ|Ψ|Ω|α|β|γ|δ|ε|ζ|η|θ|ι|κ|λ|μ|ν|ξ|ο|π|ρ|ς|σ|τ|υ|φ|χ|ψ|ω|ϑ|ϒ|ϖ| | | |‌|‍|‎|‏|–|—|‘|’|‚|“|”|„|†|‡|•|…|‰|′|″|‹|›|‾|⁄|€|ℑ|℘|ℜ|™|ℵ|←|↑|→|↓|↔|↵|⇐|⇑|⇒|⇓|⇔|∀|∂|∃|∅|∇|∈|∉|∋|∏|∑|−|∗|√|∝|∞|∠|∧|∨|∩|∪|∫|∴|∼|≅|≈|≠|≡|≤|≥|⊂|⊃|⊄|⊆|⊇|⊕|⊗|⊥|⋅|⌈|⌉|⌊|⌋|〈|〉|◊|♠|♣|♥|♦|"|&|'|<|>| |¡|¢|£|¤|¥|¦|§|¨|©|ª|«|¬|­|®|¯|°|±|²|³|´|µ|¶|·|¸|¹|º|»|¼|½|¾|¿|À|Á|Â|Ã|Ä|Å|Æ|Ç|È|É|Ê|Ë|Ì|Í|Î|Ï|Ð|Ñ|Ò|Ó|Ô|Õ|Ö|×|Ø|Ù|Ú|Û|Ü|Ý|Þ|ß|à|á|â|ã|ä|å|æ|ç|è|é|ê|ë|ì|í|î|ï|ð|ñ|ò|ó|ô|õ|ö|÷|ø|Ù|Ú|Û|Ü|ý|þ|ÿ|Œ|œ|Š|š|Ÿ|ƒ|ˆ|˜|Α|Β|Γ|Δ|Ε|Ζ|Η|Θ|Ι|Κ|Λ|Μ|Ν|Ξ|Ο|Π|Ρ|Σ|Τ|Υ|Φ|Χ|Ψ|Ω|α|β|γ|δ|ε|ζ|η|θ|ι|κ|λ|μ|ν|ξ|ο|π|ρ|ς|σ|τ|υ|φ|χ|ψ|ω|ϑ|&Upsih;|ϖ| | | |‌|‍|‎|‏|–|—|‘|’|‚|“|”|„|†|‡|•|…|‰|′|″|‹|›|‾|⁄|€|ℑ|℘|ℜ|™|ℵ|←|↑|→|↓|↔|↵|⇐|&UArr;|⇒|⇓|⇔|∀|∂|∃|∅|∇|∈|∉|∋|∏|∑|−|∗|√|∝|∞|∠|∧|∨|∩|∪|∫|∴|∼|≅|≈|≠|≡|≤|≥|⊂|⊃|⊄|⊆|⊇|⊕|⊗|⊥|⋅|⌈|⌉|⌊|⌋|⟨|⟩|◊|♠|♣|♥|♦)" 63 | attributes:@{ 64 | NSForegroundColorAttributeName : [UIColor blackColor], 65 | NSFontAttributeName: self.boldFont, 66 | NSDocumentTypeDocumentAttribute: NSPlainTextDocumentType}], 67 | [CYRToken tokenWithName:@"comment" 68 | expression:@"" 69 | attributes:@{ 70 | NSForegroundColorAttributeName : RGB(31, 131, 0), 71 | NSFontAttributeName : self.italicFont 72 | }], 73 | [CYRToken tokenWithName:@"attributes" 74 | expression:@"(?<==)('|\").*?\\1(?=.*?>)" 75 | attributes:@{ 76 | NSForegroundColorAttributeName : RGB(0, 12, 255) 77 | }] 78 | ]; 79 | 80 | return solverTokens; 81 | } 82 | 83 | 84 | #pragma mark - Cleanup 85 | 86 | - (void)dealloc { 87 | [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(defaultFont))]; 88 | [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(boldFont))]; 89 | [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(italicFont))]; 90 | } 91 | 92 | 93 | #pragma mark - KVO 94 | 95 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 96 | { 97 | 98 | if ([keyPath isEqualToString:NSStringFromSelector(@selector(defaultFont))] || 99 | [keyPath isEqualToString:NSStringFromSelector(@selector(boldFont))] || 100 | [keyPath isEqualToString:NSStringFromSelector(@selector(italicFont))]) 101 | { 102 | // Reset the tokens, this will clear any existing formatting 103 | self.tokens = [self solverTokens]; 104 | } 105 | else 106 | { 107 | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 108 | } 109 | } 110 | 111 | 112 | #pragma mark - Overrides 113 | 114 | - (void)setDefaultFont:(UIFont *)defaultFont 115 | { 116 | _defaultFont = defaultFont; 117 | self.font = defaultFont; 118 | } 119 | 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/ZSSRichTextEditor.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZSSRichTextEditorViewController.h 3 | // ZSSRichTextEditor 4 | // 5 | // Created by Nicholas Hubbard on 11/30/13. 6 | // Copyright (c) 2013 Zed Said Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "HRColorPickerViewController.h" 12 | #import "ZSSFontsViewController.h" 13 | 14 | /** 15 | * The types of toolbar items that can be added 16 | */ 17 | static NSString * const ZSSRichTextEditorToolbarBold = @"com.zedsaid.toolbaritem.bold"; 18 | static NSString * const ZSSRichTextEditorToolbarItalic = @"com.zedsaid.toolbaritem.italic"; 19 | static NSString * const ZSSRichTextEditorToolbarSubscript = @"com.zedsaid.toolbaritem.subscript"; 20 | static NSString * const ZSSRichTextEditorToolbarSuperscript = @"com.zedsaid.toolbaritem.superscript"; 21 | static NSString * const ZSSRichTextEditorToolbarStrikeThrough = @"com.zedsaid.toolbaritem.strikeThrough"; 22 | static NSString * const ZSSRichTextEditorToolbarUnderline = @"com.zedsaid.toolbaritem.underline"; 23 | static NSString * const ZSSRichTextEditorToolbarRemoveFormat = @"com.zedsaid.toolbaritem.removeFormat"; 24 | static NSString * const ZSSRichTextEditorToolbarJustifyLeft = @"com.zedsaid.toolbaritem.justifyLeft"; 25 | static NSString * const ZSSRichTextEditorToolbarJustifyCenter = @"com.zedsaid.toolbaritem.justifyCenter"; 26 | static NSString * const ZSSRichTextEditorToolbarJustifyRight = @"com.zedsaid.toolbaritem.justifyRight"; 27 | static NSString * const ZSSRichTextEditorToolbarJustifyFull = @"com.zedsaid.toolbaritem.justifyFull"; 28 | static NSString * const ZSSRichTextEditorToolbarH1 = @"com.zedsaid.toolbaritem.h1"; 29 | static NSString * const ZSSRichTextEditorToolbarH2 = @"com.zedsaid.toolbaritem.h2"; 30 | static NSString * const ZSSRichTextEditorToolbarH3 = @"com.zedsaid.toolbaritem.h3"; 31 | static NSString * const ZSSRichTextEditorToolbarH4 = @"com.zedsaid.toolbaritem.h4"; 32 | static NSString * const ZSSRichTextEditorToolbarH5 = @"com.zedsaid.toolbaritem.h5"; 33 | static NSString * const ZSSRichTextEditorToolbarH6 = @"com.zedsaid.toolbaritem.h6"; 34 | static NSString * const ZSSRichTextEditorToolbarTextColor = @"com.zedsaid.toolbaritem.textColor"; 35 | static NSString * const ZSSRichTextEditorToolbarBackgroundColor = @"com.zedsaid.toolbaritem.backgroundColor"; 36 | static NSString * const ZSSRichTextEditorToolbarUnorderedList = @"com.zedsaid.toolbaritem.unorderedList"; 37 | static NSString * const ZSSRichTextEditorToolbarOrderedList = @"com.zedsaid.toolbaritem.orderedList"; 38 | static NSString * const ZSSRichTextEditorToolbarHorizontalRule = @"com.zedsaid.toolbaritem.horizontalRule"; 39 | static NSString * const ZSSRichTextEditorToolbarIndent = @"com.zedsaid.toolbaritem.indent"; 40 | static NSString * const ZSSRichTextEditorToolbarOutdent = @"com.zedsaid.toolbaritem.outdent"; 41 | static NSString * const ZSSRichTextEditorToolbarInsertImage = @"com.zedsaid.toolbaritem.insertImage"; 42 | static NSString * const ZSSRichTextEditorToolbarInsertImageFromDevice = @"com.zedsaid.toolbaritem.insertImageFromDevice"; 43 | static NSString * const ZSSRichTextEditorToolbarInsertLink = @"com.zedsaid.toolbaritem.insertLink"; 44 | static NSString * const ZSSRichTextEditorToolbarRemoveLink = @"com.zedsaid.toolbaritem.removeLink"; 45 | static NSString * const ZSSRichTextEditorToolbarQuickLink = @"com.zedsaid.toolbaritem.quickLink"; 46 | static NSString * const ZSSRichTextEditorToolbarUndo = @"com.zedsaid.toolbaritem.undo"; 47 | static NSString * const ZSSRichTextEditorToolbarRedo = @"com.zedsaid.toolbaritem.redo"; 48 | static NSString * const ZSSRichTextEditorToolbarViewSource = @"com.zedsaid.toolbaritem.viewSource"; 49 | static NSString * const ZSSRichTextEditorToolbarParagraph = @"com.zedsaid.toolbaritem.paragraph"; 50 | static NSString * const ZSSRichTextEditorToolbarAll = @"com.zedsaid.toolbaritem.all"; 51 | static NSString * const ZSSRichTextEditorToolbarNone = @"com.zedsaid.toolbaritem.none"; 52 | static NSString * const ZSSRichTextEditorToolbarFonts = @"com.zedsaid.toolbaritem.fonts"; 53 | 54 | // source string for parsing JSON 55 | static NSString * const ZSSEditorHTML = @"zss_editor.getHTML();"; 56 | static NSString * const ZSSEditorText = @"zss_editor.getText();"; 57 | static NSString * const ZSSEditorContent = @"document.activeElement.id=='zss_editor_content'"; 58 | 59 | @class ZSSBarButtonItem; 60 | 61 | /** 62 | * The viewController used with ZSSRichTextEditor 63 | */ 64 | @interface ZSSRichTextEditor : UIViewController 65 | 66 | 67 | /** 68 | * The base URL to use for the webView 69 | */ 70 | @property (nonatomic, strong) NSURL *baseURL; 71 | 72 | /** 73 | * If the HTML should be formatted to be pretty 74 | */ 75 | @property (nonatomic) BOOL formatHTML; 76 | 77 | /** 78 | * If the keyboard should be shown when the editor loads 79 | */ 80 | @property (nonatomic) BOOL shouldShowKeyboard; 81 | 82 | /** 83 | * If the toolbar should always be shown or not 84 | */ 85 | @property (nonatomic) BOOL alwaysShowToolbar; 86 | 87 | /** 88 | * If the sub class recieves text did change events or not 89 | */ 90 | @property (nonatomic) BOOL receiveEditorDidChangeEvents; 91 | 92 | /** 93 | * The placeholder text to use if there is no editor content 94 | */ 95 | @property (nonatomic, strong) NSString *placeholder; 96 | 97 | /** 98 | * Toolbar items to include 99 | */ 100 | @property (nonatomic, strong) NSArray *enabledToolbarItems; 101 | 102 | /** 103 | * Color to tint the toolbar items 104 | */ 105 | @property (nonatomic, strong) UIColor *toolbarItemTintColor; 106 | 107 | /** 108 | * Color to tint selected items 109 | */ 110 | @property (nonatomic, strong) UIColor *toolbarItemSelectedTintColor; 111 | 112 | /** 113 | * Sets the HTML for the entire editor 114 | * 115 | * @param html HTML string to set for the editor 116 | * 117 | */ 118 | - (void)setHTML:(NSString *)html; 119 | 120 | /** 121 | * Returns the HTML from the Rich Text Editor 122 | * 123 | */ 124 | - (void)getHTML:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler; 125 | 126 | /** 127 | * Returns the plain text from the Rich Text Editor 128 | * 129 | */ 130 | - (void)getText:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler; 131 | 132 | /** 133 | * Inserts HTML at the caret position 134 | * 135 | * @param html HTML string to insert 136 | * 137 | */ 138 | - (void)insertHTML:(NSString *)html; 139 | 140 | /** 141 | * Manually focuses on the text editor 142 | */ 143 | - (void)focusTextEditor; 144 | 145 | /** 146 | * Manually dismisses on the text editor 147 | */ 148 | - (void)blurTextEditor; 149 | 150 | /** 151 | * Shows the insert image dialog with optinal inputs 152 | * 153 | * @param url The URL for the image 154 | * @param alt The alt for the image 155 | */ 156 | - (void)showInsertImageDialogWithLink:(NSString *)url alt:(NSString *)alt; 157 | 158 | /** 159 | * Inserts an image 160 | * 161 | * @param url The URL for the image 162 | * @param alt The alt attribute for the image 163 | */ 164 | - (void)insertImage:(NSString *)url alt:(NSString *)alt; 165 | 166 | /** 167 | * Shows the insert link dialog with optional inputs 168 | * 169 | * @param url The URL for the link 170 | * @param title The tile for the link 171 | */ 172 | - (void)showInsertLinkDialogWithLink:(NSString *)url title:(NSString *)title; 173 | 174 | /** 175 | * Inserts a link 176 | * 177 | * @param url The URL for the link 178 | * @param title The title for the link 179 | */ 180 | - (void)insertLink:(NSString *)url title:(NSString *)title; 181 | 182 | /** 183 | * Gets called when the insert URL picker button is tapped in an alertView 184 | * 185 | * @warning The default implementation of this method is blank and does nothing 186 | */ 187 | - (void)showInsertURLAlternatePicker; 188 | 189 | /** 190 | * Gets called when the insert Image picker button is tapped in an alertView 191 | * 192 | * @warning The default implementation of this method is blank and does nothing 193 | */ 194 | - (void)showInsertImageAlternatePicker; 195 | 196 | /** 197 | * Dismisses the current AlertView 198 | */ 199 | - (void)dismissAlertView; 200 | 201 | /** 202 | * Add a custom UIBarButtonItem by using a UIButton 203 | */ 204 | - (void)addCustomToolbarItemWithButton:(UIButton*)button; 205 | 206 | /** 207 | * Add a custom ZSSBarButtonItem 208 | */ 209 | - (void)addCustomToolbarItem:(ZSSBarButtonItem *)item; 210 | 211 | /** 212 | * Scroll event callback with position 213 | */ 214 | - (void)editorDidScrollWithPosition:(NSInteger)position; 215 | 216 | /** 217 | * Text change callback with text and html 218 | */ 219 | - (void)editorDidChangeWithText:(NSString *)text andHTML:(NSString *)html; 220 | 221 | /** 222 | * Hashtag callback with word 223 | */ 224 | - (void)hashtagRecognizedWithWord:(NSString *)word; 225 | 226 | /** 227 | * Mention callback with word 228 | */ 229 | - (void)mentionRecognizedWithWord:(NSString *)word; 230 | 231 | /** 232 | * Set custom css 233 | */ 234 | - (void)setCSS:(NSString *)css; 235 | 236 | @end 237 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/CYRLayoutManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // CYRLayoutManager.h 3 | // 4 | // Version 0.2.0 5 | // 6 | // Created by Illya Busigin on 01/05/2014. 7 | // Copyright (c) 2014 Cyrillian, Inc. 8 | // 9 | // Distributed under MIT license. 10 | // Get the latest version from here: 11 | // 12 | // https://github.com/illyabusigin/CYRTextView 13 | // Original implementation taken from: https://github.com/alldritt/TextKit_LineNumbers 14 | // 15 | // The MIT License (MIT) 16 | // 17 | // Copyright (c) 2014 Cyrillian, Inc. 18 | // 19 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 20 | // this software and associated documentation files (the "Software"), to deal in 21 | // the Software without restriction, including without limitation the rights to 22 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 23 | // the Software, and to permit persons to whom the Software is furnished to do so, 24 | // subject to the following conditions: 25 | // 26 | // The above copyright notice and this permission notice shall be included in all 27 | // copies or substantial portions of the Software. 28 | // 29 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 31 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 32 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 33 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 34 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 35 | 36 | #import "CYRLayoutManager.h" 37 | 38 | static CGFloat kMinimumGutterWidth = 30.f; 39 | 40 | @interface CYRLayoutManager () 41 | 42 | @property (nonatomic, assign) CGFloat gutterWidth; 43 | @property (nonatomic, assign) UIEdgeInsets lineAreaInset; 44 | 45 | @property (nonatomic) NSUInteger lastParaLocation; 46 | @property (nonatomic) NSUInteger lastParaNumber; 47 | 48 | @end 49 | 50 | @implementation CYRLayoutManager 51 | 52 | #pragma mark - Initialization & Setup 53 | 54 | - (instancetype)init 55 | { 56 | self = [super init]; 57 | 58 | if (self) 59 | { 60 | [self _commonSetup]; 61 | } 62 | 63 | return self; 64 | } 65 | 66 | - (instancetype)initWithCoder:(NSCoder *)aDecoder 67 | { 68 | self = [super initWithCoder:aDecoder]; 69 | 70 | if (self) 71 | { 72 | [self _commonSetup]; 73 | } 74 | 75 | return self; 76 | } 77 | 78 | - (void)_commonSetup 79 | { 80 | self.gutterWidth = kMinimumGutterWidth; 81 | self.selectedRange = NSMakeRange(0, 0); 82 | 83 | self.lineAreaInset = UIEdgeInsetsMake(0, 10, 0, 4); 84 | self.lineNumberColor = [UIColor grayColor]; 85 | self.lineNumberFont = [UIFont systemFontOfSize:10.0f]; 86 | } 87 | 88 | 89 | #pragma mark - Convenience 90 | 91 | - (CGRect)paragraphRectForRange:(NSRange)range 92 | { 93 | range = [self.textStorage.string paragraphRangeForRange:range]; 94 | range = [self glyphRangeForCharacterRange:range actualCharacterRange:NULL]; 95 | 96 | CGRect startRect = [self lineFragmentRectForGlyphAtIndex:range.location effectiveRange:NULL]; 97 | CGRect endRect = [self lineFragmentRectForGlyphAtIndex:range.location + range.length - 1 effectiveRange:NULL]; 98 | 99 | CGRect paragraphRectForRange = CGRectUnion(startRect, endRect); 100 | paragraphRectForRange = CGRectOffset(paragraphRectForRange, _gutterWidth, 8); 101 | 102 | return paragraphRectForRange; 103 | } 104 | 105 | - (NSUInteger) _paraNumberForRange:(NSRange) charRange 106 | { 107 | // NSString does not provide a means of efficiently determining the paragraph number of a range of text. This code 108 | // attempts to optimize what would normally be a series linear searches by keeping track of the last paragraph number 109 | // found and uses that as the starting point for next paragraph number search. This works (mostly) because we 110 | // are generally asked for continguous increasing sequences of paragraph numbers. Also, this code is called in the 111 | // course of drawing a pagefull of text, and so even when moving back, the number of paragraphs to search for is 112 | // relativly low, even in really long bodies of text. 113 | // 114 | // This all falls down when the user edits the text, and can potentially invalidate the cached paragraph number which 115 | // causes a (potentially lengthy) search from the beginning of the string. 116 | 117 | if (charRange.location == self.lastParaLocation) 118 | return self.lastParaNumber; 119 | else if (charRange.location < self.lastParaLocation) 120 | { 121 | // We need to look backwards from the last known paragraph for the new paragraph range. This generally happens 122 | // when the text in the UITextView scrolls downward, revaling paragraphs before/above the ones previously drawn. 123 | 124 | NSString* s = self.textStorage.string; 125 | __block NSUInteger paraNumber = self.lastParaNumber; 126 | 127 | [s enumerateSubstringsInRange:NSMakeRange(charRange.location, self.lastParaLocation - charRange.location) 128 | options:NSStringEnumerationByParagraphs | 129 | NSStringEnumerationSubstringNotRequired | 130 | NSStringEnumerationReverse 131 | usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){ 132 | if (enclosingRange.location <= charRange.location) { 133 | *stop = YES; 134 | } 135 | --paraNumber; 136 | }]; 137 | 138 | self.lastParaLocation = charRange.location; 139 | self.lastParaNumber = paraNumber; 140 | 141 | return paraNumber; 142 | } 143 | else 144 | { 145 | // We need to look forward from the last known paragraph for the new paragraph range. This generally happens 146 | // when the text in the UITextView scrolls upwards, revealing paragraphs that follow the ones previously drawn. 147 | 148 | NSString* s = self.textStorage.string; 149 | __block NSUInteger paraNumber = self.lastParaNumber; 150 | 151 | [s enumerateSubstringsInRange:NSMakeRange(self.lastParaLocation, charRange.location - self.lastParaLocation) 152 | options:NSStringEnumerationByParagraphs | NSStringEnumerationSubstringNotRequired 153 | usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){ 154 | if (enclosingRange.location >= charRange.location) { 155 | *stop = YES; 156 | } 157 | ++paraNumber; 158 | }]; 159 | 160 | self.lastParaLocation = charRange.location; 161 | self.lastParaNumber = paraNumber; 162 | 163 | return paraNumber; 164 | } 165 | } 166 | 167 | 168 | #pragma mark - Layouting 169 | 170 | - (void)processEditingForTextStorage:(NSTextStorage *)textStorage edited:(NSTextStorageEditActions)editMask range:(NSRange)newCharRange changeInLength:(NSInteger)delta invalidatedRange:(NSRange)invalidatedCharRange 171 | { 172 | [super processEditingForTextStorage:textStorage edited:editMask range:newCharRange changeInLength:delta invalidatedRange:invalidatedCharRange]; 173 | 174 | if (invalidatedCharRange.location < self.lastParaLocation) 175 | { 176 | // When the backing store is edited ahead the cached paragraph location, invalidate the cache and force a complete 177 | // recalculation. We cannot be much smarter than this because we don't know how many paragraphs have been deleted 178 | // since the text has already been removed from the backing store. 179 | self.lastParaLocation = 0; 180 | self.lastParaNumber = 0; 181 | } 182 | } 183 | 184 | 185 | #pragma mark - Drawing 186 | 187 | - (void) drawBackgroundForGlyphRange:(NSRange)glyphsToShow atPoint:(CGPoint)origin 188 | { 189 | [super drawBackgroundForGlyphRange:glyphsToShow atPoint:origin]; 190 | 191 | // Draw line numbers. Note that the background for line number gutter is drawn by the LineNumberTextView class. 192 | NSDictionary* atts = @{NSFontAttributeName : _lineNumberFont , 193 | NSForegroundColorAttributeName : _lineNumberColor}; 194 | 195 | [self enumerateLineFragmentsForGlyphRange:glyphsToShow 196 | usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer *textContainer, NSRange glyphRange, BOOL *stop) { 197 | NSRange charRange = [self characterRangeForGlyphRange:glyphRange actualGlyphRange:nil]; 198 | NSRange paraRange = [self.textStorage.string paragraphRangeForRange:charRange]; 199 | 200 | BOOL showCursorRect = NSLocationInRange(self->_selectedRange.location, paraRange); 201 | 202 | if (showCursorRect) 203 | { 204 | CGContextRef context = UIGraphicsGetCurrentContext(); 205 | CGRect cursorRect = CGRectMake(0, usedRect.origin.y + 8, self->_gutterWidth, usedRect.size.height); 206 | 207 | CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:0.9 alpha:1].CGColor); 208 | CGContextFillRect(context, cursorRect); 209 | } 210 | 211 | // Only draw line numbers for the paragraph's first line fragment. Subsequent fragments are wrapped portions of the paragraph and don't get the line number. 212 | if (charRange.location == paraRange.location) { 213 | CGRect gutterRect = CGRectOffset(CGRectMake(0, rect.origin.y, self->_gutterWidth, rect.size.height), origin.x, origin.y); 214 | NSUInteger paraNumber = [self _paraNumberForRange:charRange]; 215 | NSString* ln = [NSString stringWithFormat:@"%ld", (unsigned long) paraNumber + 1]; 216 | CGSize size = [ln sizeWithAttributes:atts]; 217 | 218 | [ln drawInRect:CGRectOffset(gutterRect, CGRectGetWidth(gutterRect) - self->_lineAreaInset.right - size.width - self->_gutterWidth, (CGRectGetHeight(gutterRect) - size.height) / 2.0) 219 | withAttributes:atts]; 220 | } 221 | 222 | }]; 223 | } 224 | 225 | @end 226 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/CYRTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CYRTextView.m 3 | // 4 | // Version 0.2.0 5 | // 6 | // Created by Illya Busigin on 01/05/2014. 7 | // Copyright (c) 2014 Cyrillian, Inc. 8 | // Copyright (c) 2013 Dominik Hauser 9 | // Copyright (c) 2013 Sam Rijs 10 | // 11 | // Distributed under MIT license. 12 | // Get the latest version from here: 13 | // 14 | // https://github.com/illyabusigin/CYRTextView 15 | // 16 | // The MIT License (MIT) 17 | // 18 | // Copyright (c) 2014 Cyrillian, Inc. 19 | // 20 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 21 | // this software and associated documentation files (the "Software"), to deal in 22 | // the Software without restriction, including without limitation the rights to 23 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 24 | // the Software, and to permit persons to whom the Software is furnished to do so, 25 | // subject to the following conditions: 26 | // 27 | // The above copyright notice and this permission notice shall be included in all 28 | // copies or substantial portions of the Software. 29 | // 30 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 31 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 32 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 33 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 34 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 35 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 36 | 37 | #import "CYRTextView.h" 38 | #import "CYRLayoutManager.h" 39 | #import "CYRTextStorage.h" 40 | 41 | #define RGB(r,g,b) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:1.0f] 42 | 43 | static void *CYRTextViewContext = &CYRTextViewContext; 44 | static const float kCursorVelocity = 1.0f/8.0f; 45 | 46 | @interface CYRTextView () 47 | 48 | @property (nonatomic, strong) CYRLayoutManager *lineNumberLayoutManager; 49 | @property (nonatomic, strong) CYRTextStorage *syntaxTextStorage; 50 | 51 | @end 52 | 53 | @implementation CYRTextView 54 | { 55 | NSRange startRange; 56 | } 57 | 58 | #pragma mark - Initialization & Setup 59 | 60 | - (id)initWithFrame:(CGRect)frame 61 | { 62 | CYRTextStorage *textStorage = [CYRTextStorage new]; 63 | CYRLayoutManager *layoutManager = [CYRLayoutManager new]; 64 | 65 | self.lineNumberLayoutManager = layoutManager; 66 | 67 | NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; 68 | 69 | // Wrap text to the text view's frame 70 | textContainer.widthTracksTextView = YES; 71 | 72 | [layoutManager addTextContainer:textContainer]; 73 | 74 | [textStorage removeLayoutManager:textStorage.layoutManagers.firstObject]; 75 | [textStorage addLayoutManager:layoutManager]; 76 | 77 | self.syntaxTextStorage = textStorage; 78 | 79 | if ((self = [super initWithFrame:frame textContainer:textContainer])) 80 | { 81 | self.contentMode = UIViewContentModeRedraw; // causes drawRect: to be called on frame resizing and device rotation 82 | 83 | [self _commonSetup]; 84 | } 85 | 86 | return self; 87 | } 88 | 89 | - (void)_commonSetup 90 | { 91 | // Setup observers 92 | [self addObserver:self forKeyPath:NSStringFromSelector(@selector(font)) options:NSKeyValueObservingOptionNew context:CYRTextViewContext]; 93 | [self addObserver:self forKeyPath:NSStringFromSelector(@selector(selectedTextRange)) options:NSKeyValueObservingOptionNew context:CYRTextViewContext]; 94 | [self addObserver:self forKeyPath:NSStringFromSelector(@selector(selectedRange)) options:NSKeyValueObservingOptionNew context:CYRTextViewContext]; 95 | 96 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTextViewDidChangeNotification:) name:UITextViewTextDidChangeNotification object:self]; 97 | 98 | // Setup defaults 99 | self.font = [UIFont systemFontOfSize:16.0f]; 100 | self.autocapitalizationType = UITextAutocapitalizationTypeNone; 101 | self.autocorrectionType = UITextAutocorrectionTypeNo; 102 | self.lineCursorEnabled = YES; 103 | self.gutterBackgroundColor = [UIColor colorWithWhite:0.95 alpha:1]; 104 | self.gutterLineColor = [UIColor lightGrayColor]; 105 | 106 | // Inset the content to make room for line numbers 107 | self.textContainerInset = UIEdgeInsetsMake(8, self.lineNumberLayoutManager.gutterWidth, 8, 0); 108 | 109 | // Setup the gesture recognizers 110 | _singleFingerPanRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(singleFingerPanHappend:)]; 111 | _singleFingerPanRecognizer.maximumNumberOfTouches = 1; 112 | [self addGestureRecognizer:_singleFingerPanRecognizer]; 113 | 114 | _doubleFingerPanRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(doubleFingerPanHappend:)]; 115 | _doubleFingerPanRecognizer.minimumNumberOfTouches = 2; 116 | [self addGestureRecognizer:_doubleFingerPanRecognizer]; 117 | } 118 | 119 | 120 | #pragma mark - Cleanup 121 | 122 | - (void)dealloc 123 | { 124 | [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(font))]; 125 | [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(selectedTextRange))]; 126 | [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(selectedRange))]; 127 | } 128 | 129 | 130 | #pragma mark - KVO 131 | 132 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 133 | { 134 | if ([keyPath isEqualToString:NSStringFromSelector(@selector(font))] && context == CYRTextViewContext) 135 | { 136 | // Whenever the UITextView font is changed we want to keep a reference in the stickyFont ivar. We do this to counteract a bug where the underlying font can be changed without notice and cause undesired behaviour. 137 | self.syntaxTextStorage.defaultFont = self.font; 138 | } 139 | else if (([keyPath isEqualToString:NSStringFromSelector(@selector(selectedTextRange))] || 140 | [keyPath isEqualToString:NSStringFromSelector(@selector(selectedRange))]) && context == CYRTextViewContext) 141 | { 142 | [self setNeedsDisplay]; 143 | } 144 | else 145 | { 146 | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 147 | } 148 | } 149 | 150 | 151 | #pragma mark - Notifications 152 | 153 | - (void)handleTextViewDidChangeNotification:(NSNotification *)notification 154 | { 155 | if (notification.object == self) 156 | { 157 | CGRect line = [self caretRectForPosition: self.selectedTextRange.start]; 158 | CGFloat overflow = line.origin.y + line.size.height - ( self.contentOffset.y + self.bounds.size.height - self.contentInset.bottom - self.contentInset.top ); 159 | 160 | if ( overflow > 0 ) 161 | { 162 | // We are at the bottom of the visible text and introduced a line feed, scroll down (iOS 7 does not do it) 163 | // Scroll caret to visible area 164 | CGPoint offset = self.contentOffset; 165 | offset.y += overflow + 7; // leave 7 pixels margin 166 | // Cannot animate with setContentOffset:animated: or caret will not appear 167 | // [UIView animateWithDuration:.2 animations:^{ 168 | // [self setContentOffset:offset]; 169 | // }]; 170 | } 171 | } 172 | } 173 | 174 | 175 | #pragma mark - Overrides 176 | 177 | - (void)setTokens:(NSMutableArray *)tokens 178 | { 179 | [self.syntaxTextStorage setTokens:tokens]; 180 | } 181 | 182 | - (NSArray *)tokens 183 | { 184 | CYRTextStorage *syntaxTextStorage = (CYRTextStorage *)self.textStorage; 185 | 186 | return syntaxTextStorage.tokens; 187 | } 188 | 189 | - (void)setText:(NSString *)text 190 | { 191 | UITextRange *textRange = [self textRangeFromPosition:self.beginningOfDocument toPosition:self.endOfDocument]; 192 | [self replaceRange:textRange withText:text]; 193 | } 194 | 195 | 196 | #pragma mark - Line Drawing 197 | 198 | // Original implementation sourced from: https://github.com/alldritt/TextKit_LineNumbers 199 | - (void)drawRect:(CGRect)rect 200 | { 201 | // Drag the line number gutter background. The line numbers them selves are drawn by LineNumberLayoutManager. 202 | CGContextRef context = UIGraphicsGetCurrentContext(); 203 | CGRect bounds = self.bounds; 204 | 205 | CGFloat height = MAX(CGRectGetHeight(bounds), self.contentSize.height) + 200; 206 | 207 | // Set the regular fill 208 | CGContextSetFillColorWithColor(context, self.gutterBackgroundColor.CGColor); 209 | CGContextFillRect(context, CGRectMake(bounds.origin.x, bounds.origin.y, self.lineNumberLayoutManager.gutterWidth, height)); 210 | 211 | // Draw line 212 | CGContextSetFillColorWithColor(context, self.gutterLineColor.CGColor); 213 | CGContextFillRect(context, CGRectMake(self.lineNumberLayoutManager.gutterWidth, bounds.origin.y, 0.5, height)); 214 | 215 | if (_lineCursorEnabled) 216 | { 217 | self.lineNumberLayoutManager.selectedRange = self.selectedRange; 218 | 219 | NSRange glyphRange = [self.lineNumberLayoutManager.textStorage.string paragraphRangeForRange:self.selectedRange]; 220 | glyphRange = [self.lineNumberLayoutManager glyphRangeForCharacterRange:glyphRange actualCharacterRange:NULL]; 221 | self.lineNumberLayoutManager.selectedRange = glyphRange; 222 | [self.lineNumberLayoutManager invalidateDisplayForGlyphRange:glyphRange]; 223 | } 224 | 225 | [super drawRect:rect]; 226 | } 227 | 228 | 229 | #pragma mark - Gestures 230 | 231 | // Sourced from: https://github.com/srijs/NLTextView 232 | - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer 233 | { 234 | // Only accept horizontal pans for the code navigation to preserve correct scrolling behaviour. 235 | if (gestureRecognizer == _singleFingerPanRecognizer || gestureRecognizer == _doubleFingerPanRecognizer) 236 | { 237 | CGPoint translation = [gestureRecognizer translationInView:self]; 238 | 239 | float translationX = (float)translation.x; 240 | float translationY = (float)translation.y; 241 | 242 | return fabsf(translationX) > fabsf(translationY); 243 | } 244 | 245 | return YES; 246 | 247 | } 248 | 249 | // Sourced from: https://github.com/srijs/NLTextView 250 | - (void)singleFingerPanHappend:(UIPanGestureRecognizer *)sender 251 | { 252 | if (sender.state == UIGestureRecognizerStateBegan) 253 | { 254 | startRange = self.selectedRange; 255 | } 256 | 257 | CGFloat cursorLocation = MAX(startRange.location + [sender translationInView:self].x * kCursorVelocity, 0); 258 | 259 | self.selectedRange = NSMakeRange(cursorLocation, 0); 260 | } 261 | 262 | // Sourced from: https://github.com/srijs/NLTextView 263 | - (void)doubleFingerPanHappend:(UIPanGestureRecognizer *)sender 264 | { 265 | if (sender.state == UIGestureRecognizerStateBegan) 266 | { 267 | startRange = self.selectedRange; 268 | } 269 | 270 | CGFloat cursorLocation = MAX(startRange.location + [sender translationInView:self].x * kCursorVelocity, 0); 271 | 272 | float location = startRange.location - cursorLocation; 273 | 274 | if (cursorLocation > startRange.location) 275 | { 276 | self.selectedRange = NSMakeRange(startRange.location, fabsf(location)); 277 | } 278 | else 279 | { 280 | self.selectedRange = NSMakeRange(cursorLocation, fabsf(location)); 281 | } 282 | } 283 | 284 | @end 285 | -------------------------------------------------------------------------------- /ZSSRichTextEditor/Source/Third Party/HRColorPickerView.m: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2011 Ryota Hayashi 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #import "HRColorPickerView.h" 29 | #import "HRCgUtil.h" 30 | #import "HRBrightnessCursor.h" 31 | #import "HRColorCursor.h" 32 | 33 | @interface HRColorPickerView() 34 | - (void)createCacheImage; 35 | - (void)update; 36 | - (void)updateBrightnessCursor; 37 | - (void)updateColorCursor; 38 | - (void)clearInput; 39 | - (void)setCurrentTouchPointInView:(UITouch *)touch; 40 | - (void)setNeedsDisplay15FPS; 41 | @end 42 | 43 | @implementation HRColorPickerView 44 | 45 | @synthesize delegate; 46 | 47 | + (HRColorPickerStyle)defaultStyle 48 | { 49 | HRColorPickerStyle style; 50 | style.width = 320.0f; 51 | style.headerHeight = 106.0f; 52 | style.colorMapTileSize = 15.0f; 53 | style.colorMapSizeWidth = 20; 54 | style.colorMapSizeHeight = 20; 55 | style.brightnessLowerLimit = 0.4f; 56 | style.saturationUpperLimit = 0.95f; 57 | return style; 58 | } 59 | 60 | // j5136p1 12/08/2014 : Extended the method with size to fit the current view 61 | + (HRColorPickerStyle)fitScreenStyleWithSize:(CGSize)size 62 | { 63 | size.height -= 44.f; 64 | 65 | HRColorPickerStyle style = [HRColorPickerView defaultStyle]; 66 | style.colorMapSizeHeight = (size.height - style.headerHeight)/style.colorMapTileSize; 67 | style.colorMapSizeWidth = size.width/style.colorMapTileSize; 68 | 69 | style.width = size.width; 70 | 71 | float colorMapMargin = (style.width - (style.colorMapSizeWidth*style.colorMapTileSize))/2.f; 72 | style.headerHeight = size.height - (style.colorMapSizeHeight*style.colorMapTileSize) - colorMapMargin; 73 | 74 | return style; 75 | } 76 | 77 | + (HRColorPickerStyle)fullColorStyle 78 | { 79 | HRColorPickerStyle style = [HRColorPickerView defaultStyle]; 80 | style.brightnessLowerLimit = 0.0f; 81 | style.saturationUpperLimit = 1.0f; 82 | return style; 83 | } 84 | 85 | // j5136p1 12/08/2014 : Extended the method with size to fit the current view 86 | + (HRColorPickerStyle)fitScreenFullColorStyleWithSize:(CGSize)size 87 | { 88 | HRColorPickerStyle style = [HRColorPickerView fitScreenStyleWithSize:size]; 89 | style.brightnessLowerLimit = 0.0f; 90 | style.saturationUpperLimit = 1.0f; 91 | return style; 92 | } 93 | 94 | + (CGSize)sizeWithStyle:(HRColorPickerStyle)style 95 | { 96 | CGSize colorMapSize = CGSizeMake(style.colorMapTileSize * style.colorMapSizeWidth, style.colorMapTileSize * style.colorMapSizeHeight); 97 | float colorMapMargin = (style.width - colorMapSize.width) / 2.0f; 98 | return CGSizeMake(style.width, style.headerHeight + colorMapSize.height + colorMapMargin); 99 | } 100 | 101 | - (id)initWithFrame:(CGRect)frame defaultColor:(const HRRGBColor)defaultColor 102 | { 103 | return [self initWithStyle:[HRColorPickerView defaultStyle] defaultColor:defaultColor]; 104 | } 105 | 106 | - (id)initWithStyle:(HRColorPickerStyle)style defaultColor:(const HRRGBColor)defaultColor{ 107 | CGSize size = [HRColorPickerView sizeWithStyle:style]; 108 | CGRect frame = CGRectMake(0.0f, 0.0f, size.width, size.height); 109 | 110 | self = [super initWithFrame:frame]; 111 | if (self) { 112 | _defaultRgbColor = defaultColor; 113 | _animating = FALSE; 114 | 115 | // RGBのデフォルトカラーをHSVに変換 116 | HSVColorFromRGBColor(&_defaultRgbColor, &_currentHsvColor); 117 | 118 | // パーツの配置 119 | CGSize colorMapSize = CGSizeMake(style.colorMapTileSize * style.colorMapSizeWidth, style.colorMapTileSize * style.colorMapSizeHeight); 120 | float colorMapSpace = (style.width - colorMapSize.width) / 2.0f; 121 | float headerPartsOriginY = (style.headerHeight - 40.0f)/2.0f; 122 | _currentColorFrame = CGRectMake(10.0f, headerPartsOriginY, 40.0f, 40.0f); 123 | _brightnessPickerFrame = CGRectMake(120.0f, headerPartsOriginY, style.width - 120.0f - 10.0f, 40.0f); 124 | _brightnessPickerTouchFrame = CGRectMake(_brightnessPickerFrame.origin.x - 20.0f, 125 | headerPartsOriginY, 126 | _brightnessPickerFrame.size.width + 40.0f, 127 | _brightnessPickerFrame.size.height); 128 | _brightnessPickerShadowFrame = CGRectMake(_brightnessPickerFrame.origin.x-5.0f, 129 | headerPartsOriginY-5.0f, 130 | _brightnessPickerFrame.size.width+10.0f, 131 | _brightnessPickerFrame.size.height+10.0f); 132 | 133 | _colorMapFrame = CGRectMake(colorMapSpace + 1.0f, style.headerHeight, colorMapSize.width, colorMapSize.height); 134 | 135 | _colorMapSideFrame = CGRectMake(_colorMapFrame.origin.x - 1.0f, 136 | _colorMapFrame.origin.y - 1.0f, 137 | _colorMapFrame.size.width, 138 | _colorMapFrame.size.height); 139 | 140 | _tileSize = style.colorMapTileSize; 141 | _brightnessLowerLimit = style.brightnessLowerLimit; 142 | _saturationUpperLimit = style.saturationUpperLimit; 143 | 144 | _brightnessCursor = [[HRBrightnessCursor alloc] initWithPoint:CGPointMake(_brightnessPickerFrame.origin.x, _brightnessPickerFrame.origin.y + _brightnessPickerFrame.size.height/2.0f)]; 145 | 146 | // タイルの中心にくるようにずらす 147 | _colorCursor = [[HRColorCursor alloc] initWithPoint:CGPointMake(_colorMapFrame.origin.x - ([HRColorCursor cursorSize].width - _tileSize)/2.0f - [HRColorCursor shadowSize]/2.0, 148 | _colorMapFrame.origin.y - ([HRColorCursor cursorSize].height - _tileSize)/2.0f - [HRColorCursor shadowSize]/2.0)]; 149 | [self addSubview:_brightnessCursor]; 150 | [self addSubview:_colorCursor]; 151 | 152 | // 入力の初期化 153 | _isTapStart = FALSE; 154 | _isTapped = FALSE; 155 | _wasDragStart = FALSE; 156 | _isDragStart = FALSE; 157 | _isDragging = FALSE; 158 | _isDragEnd = FALSE; 159 | 160 | // 諸々初期化 161 | [self setBackgroundColor:[UIColor colorWithWhite:0.99f alpha:1.0f]]; 162 | [self setMultipleTouchEnabled:FALSE]; 163 | 164 | _brightnessPickerShadowImage = nil; 165 | [self createCacheImage]; 166 | 167 | [self updateBrightnessCursor]; 168 | [self updateColorCursor]; 169 | 170 | // フレームレートの調整 171 | gettimeofday(&_lastDrawTime, NULL); 172 | 173 | _timeInterval15fps.tv_sec = 0.0; 174 | _timeInterval15fps.tv_usec = 1000000.0/15.0; 175 | 176 | _delegateHasSELColorWasChanged = FALSE; 177 | } 178 | return self; 179 | } 180 | 181 | 182 | - (HRRGBColor)RGBColor{ 183 | HRRGBColor rgbColor; 184 | RGBColorFromHSVColor(&_currentHsvColor, &rgbColor); 185 | return rgbColor; 186 | } 187 | 188 | - (float)BrightnessLowerLimit{ 189 | return _brightnessLowerLimit; 190 | } 191 | 192 | - (void)setBrightnessLowerLimit:(float)brightnessUnderLimit{ 193 | _brightnessLowerLimit = brightnessUnderLimit; 194 | [self updateBrightnessCursor]; 195 | } 196 | 197 | - (float)SaturationUpperLimit{ 198 | return _brightnessLowerLimit; 199 | } 200 | 201 | - (void)setSaturationUpperLimit:(float)saturationUpperLimit{ 202 | _saturationUpperLimit = saturationUpperLimit; 203 | [self updateColorCursor]; 204 | } 205 | 206 | ///////////////////////////////////////////////////////////////////////////// 207 | // 208 | // プライベート 209 | // 210 | ///////////////////////////////////////////////////////////////////////////// 211 | 212 | - (void)createCacheImage{ 213 | // 影のコストは高いので、事前に画像に書き出しておきます 214 | 215 | if (_brightnessPickerShadowImage != nil) { 216 | return; 217 | } 218 | UIGraphicsBeginImageContextWithOptions(CGSizeMake(_brightnessPickerShadowFrame.size.width, 219 | _brightnessPickerShadowFrame.size.height), 220 | FALSE, 221 | [[UIScreen mainScreen] scale]); 222 | CGContextRef brightness_picker_shadow_context = UIGraphicsGetCurrentContext(); 223 | CGContextTranslateCTM(brightness_picker_shadow_context, 0, _brightnessPickerShadowFrame.size.height); 224 | CGContextScaleCTM(brightness_picker_shadow_context, 1.0, -1.0); 225 | 226 | HRSetRoundedRectanglePath(brightness_picker_shadow_context, 227 | CGRectMake(0.0f, 0.0f, 228 | _brightnessPickerShadowFrame.size.width, 229 | _brightnessPickerShadowFrame.size.height), 5.0f); 230 | CGContextSetLineWidth(brightness_picker_shadow_context, 10.0f); 231 | CGContextSetShadow(brightness_picker_shadow_context, CGSizeMake(0.0f, 0.0f), 10.0f); 232 | CGContextDrawPath(brightness_picker_shadow_context, kCGPathStroke); 233 | 234 | _brightnessPickerShadowImage = CGBitmapContextCreateImage(brightness_picker_shadow_context); 235 | UIGraphicsEndImageContext(); 236 | } 237 | 238 | - (void)update{ 239 | // タッチのイベントの度、更新されます 240 | if (_isDragging || _isDragStart || _isDragEnd || _isTapped) { 241 | CGPoint touchPosition = _activeTouchPosition; 242 | if (CGRectContainsPoint(_colorMapFrame,touchPosition)) { 243 | 244 | int pixelCountX = _colorMapFrame.size.width/_tileSize; 245 | int pixelCountY = _colorMapFrame.size.height/_tileSize; 246 | HRHSVColor newHsv = _currentHsvColor; 247 | 248 | CGPoint newPosition = CGPointMake(touchPosition.x - _colorMapFrame.origin.x, touchPosition.y - _colorMapFrame.origin.y); 249 | 250 | float pixelX = (int)((newPosition.x)/_tileSize)/(float)pixelCountX; // X(色相)は1.0f=0.0fなので0.0f~0.95fの値をとるように 251 | float pixelY = (int)((newPosition.y)/_tileSize)/(float)(pixelCountY-1); // Y(彩度)は0.0f~1.0f 252 | 253 | HSVColorAt(&newHsv, pixelX, pixelY, _saturationUpperLimit, _currentHsvColor.v); 254 | 255 | if (!HRHSVColorEqualToColor(&newHsv,&_currentHsvColor)) { 256 | _currentHsvColor = newHsv; 257 | [self setNeedsDisplay15FPS]; 258 | } 259 | [self updateColorCursor]; 260 | }else if(CGRectContainsPoint(_brightnessPickerTouchFrame,touchPosition)){ 261 | if (CGRectContainsPoint(_brightnessPickerFrame,touchPosition)) { 262 | // 明度のスライダーの内側 263 | _currentHsvColor.v = (1.0f - ((touchPosition.x - _brightnessPickerFrame.origin.x )/ _brightnessPickerFrame.size.width )) * (1.0f - _brightnessLowerLimit) + _brightnessLowerLimit; 264 | }else{ 265 | // 左右をタッチした場合 266 | if (touchPosition.x < _brightnessPickerFrame.origin.x) { 267 | _currentHsvColor.v = 1.0f; 268 | }else if((_brightnessPickerFrame.origin.x + _brightnessPickerFrame.size.width) < touchPosition.x){ 269 | _currentHsvColor.v = _brightnessLowerLimit; 270 | } 271 | } 272 | [self updateBrightnessCursor]; 273 | [self updateColorCursor]; 274 | [self setNeedsDisplay15FPS]; 275 | } 276 | } 277 | [self clearInput]; 278 | } 279 | 280 | - (void)updateBrightnessCursor{ 281 | // 明度スライダーの移動 282 | float brightnessCursorX = (1.0f - (_currentHsvColor.v - _brightnessLowerLimit)/(1.0f - _brightnessLowerLimit)) * _brightnessPickerFrame.size.width + _brightnessPickerFrame.origin.x; 283 | _brightnessCursor.transform = CGAffineTransformMakeTranslation(brightnessCursorX - _brightnessPickerFrame.origin.x, 0.0f); 284 | 285 | } 286 | 287 | - (void)updateColorCursor{ 288 | // カラーマップのカーソルの移動&色の更新 289 | 290 | int pixelCountX = _colorMapFrame.size.width/_tileSize; 291 | int pixelCountY = _colorMapFrame.size.height/_tileSize; 292 | CGPoint newPosition; 293 | newPosition.x = _currentHsvColor.h * (float)pixelCountX * _tileSize + _tileSize/2.0f; 294 | newPosition.y = (1.0f - _currentHsvColor.s) * (1.0f/_saturationUpperLimit) * (float)(pixelCountY - 1) * _tileSize + _tileSize/2.0f; 295 | _colorCursorPosition.x = (int)(newPosition.x/_tileSize) * _tileSize; 296 | _colorCursorPosition.y = (int)(newPosition.y/_tileSize) * _tileSize; 297 | 298 | HRRGBColor currentRgbColor = [self RGBColor]; 299 | [_colorCursor setColorRed:currentRgbColor.r andGreen:currentRgbColor.g andBlue:currentRgbColor.b]; 300 | 301 | _colorCursor.transform = CGAffineTransformMakeTranslation(_colorCursorPosition.x,_colorCursorPosition.y); 302 | 303 | } 304 | 305 | - (void)setNeedsDisplay15FPS{ 306 | // 描画を20FPSに制限します 307 | timeval now,diff; 308 | gettimeofday(&now, NULL); 309 | timersub(&now, &_lastDrawTime, &diff); 310 | if (timercmp(&diff, &_timeInterval15fps, >)) { 311 | _lastDrawTime = now; 312 | [self setNeedsDisplay]; 313 | if (_delegateHasSELColorWasChanged) { 314 | [delegate colorWasChanged:self]; 315 | } 316 | }else{ 317 | return; 318 | } 319 | } 320 | 321 | - (void)drawRect:(CGRect)rect 322 | { 323 | CGContextRef context = UIGraphicsGetCurrentContext(); 324 | HRRGBColor currentRgbColor = [self RGBColor]; 325 | 326 | ///////////////////////////////////////////////////////////////////////////// 327 | // 328 | // 明度 329 | // 330 | ///////////////////////////////////////////////////////////////////////////// 331 | 332 | CGContextSaveGState(context); 333 | 334 | HRSetRoundedRectanglePath(context, _brightnessPickerFrame, 5.0f); 335 | CGContextClip(context); 336 | 337 | CGGradientRef gradient; 338 | CGColorSpaceRef colorSpace; 339 | size_t numLocations = 2; 340 | CGFloat locations[2] = { 0.0, 1.0 }; 341 | colorSpace = CGColorSpaceCreateDeviceRGB(); 342 | 343 | HRRGBColor darkColor; 344 | HRRGBColor lightColor; 345 | UIColor* darkColorFromHsv = [UIColor colorWithHue:_currentHsvColor.h saturation:_currentHsvColor.s brightness:_brightnessLowerLimit alpha:1.0f]; 346 | UIColor* lightColorFromHsv = [UIColor colorWithHue:_currentHsvColor.h saturation:_currentHsvColor.s brightness:1.0f alpha:1.0f]; 347 | 348 | RGBColorFromUIColor(darkColorFromHsv, &darkColor); 349 | RGBColorFromUIColor(lightColorFromHsv, &lightColor); 350 | 351 | CGFloat gradientColor[] = { 352 | darkColor.r,darkColor.g,darkColor.b,1.0f, 353 | lightColor.r,lightColor.g,lightColor.b,1.0f, 354 | }; 355 | 356 | gradient = CGGradientCreateWithColorComponents(colorSpace, gradientColor, 357 | locations, numLocations); 358 | 359 | CGPoint startPoint = CGPointMake(_brightnessPickerFrame.origin.x + _brightnessPickerFrame.size.width, _brightnessPickerFrame.origin.y); 360 | CGPoint endPoint = CGPointMake(_brightnessPickerFrame.origin.x, _brightnessPickerFrame.origin.y); 361 | CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0); 362 | 363 | // GradientとColorSpaceを開放する 364 | CGColorSpaceRelease(colorSpace); 365 | CGGradientRelease(gradient); 366 | 367 | // 明度の内側の影 (キャッシュした画像を表示するだけ) 368 | CGContextDrawImage(context, _brightnessPickerShadowFrame, _brightnessPickerShadowImage); 369 | 370 | CGContextRestoreGState(context); 371 | 372 | 373 | ///////////////////////////////////////////////////////////////////////////// 374 | // 375 | // カラーマップ 376 | // 377 | ///////////////////////////////////////////////////////////////////////////// 378 | 379 | CGContextSaveGState(context); 380 | 381 | [[UIColor colorWithWhite:0.9f alpha:1.0f] set]; 382 | CGContextAddRect(context, _colorMapSideFrame); 383 | CGContextDrawPath(context, kCGPathStroke); 384 | CGContextRestoreGState(context); 385 | 386 | CGContextSaveGState(context); 387 | float height; 388 | int pixelCountX = _colorMapFrame.size.width/_tileSize; 389 | int pixelCountY = _colorMapFrame.size.height/_tileSize; 390 | 391 | HRHSVColor pixelHsv; 392 | HRRGBColor pixelRgb; 393 | for (int j = 0; j < pixelCountY; ++j) { 394 | height = _tileSize * j + _colorMapFrame.origin.y; 395 | float pixelY = (float)j/(pixelCountY-1); // Y(彩度)は0.0f~1.0f 396 | for (int i = 0; i < pixelCountX; ++i) { 397 | float pixelX = (float)i/pixelCountX; // X(色相)は1.0f=0.0fなので0.0f~0.95fの値をとるように 398 | HSVColorAt(&pixelHsv, pixelX, pixelY, _saturationUpperLimit, _currentHsvColor.v); 399 | RGBColorFromHSVColor(&pixelHsv, &pixelRgb); 400 | CGContextSetRGBFillColor(context, pixelRgb.r, pixelRgb.g, pixelRgb.b, 1.0f); 401 | CGContextFillRect(context, CGRectMake(_tileSize*i+_colorMapFrame.origin.x, height, _tileSize-2.0f, _tileSize-2.0f)); 402 | } 403 | } 404 | 405 | CGContextRestoreGState(context); 406 | 407 | ///////////////////////////////////////////////////////////////////////////// 408 | // 409 | // カレントのカラー 410 | // 411 | ///////////////////////////////////////////////////////////////////////////// 412 | 413 | CGContextSaveGState(context); 414 | HRDrawSquareColorBatch(context, CGPointMake(CGRectGetMidX(_currentColorFrame), CGRectGetMidY(_currentColorFrame)), ¤tRgbColor, _currentColorFrame.size.width/2.0f); 415 | CGContextRestoreGState(context); 416 | 417 | ///////////////////////////////////////////////////////////////////////////// 418 | // 419 | // RGBのパーセント表示 420 | // 421 | ///////////////////////////////////////////////////////////////////////////// 422 | 423 | [[UIColor darkGrayColor] set]; 424 | 425 | float textHeight = 20.0f; 426 | float textCenter = CGRectGetMidY(_currentColorFrame) - 5.0f; 427 | [[NSString stringWithFormat:@"R:%3d%%",(int)(currentRgbColor.r*100)] drawAtPoint:CGPointMake(_currentColorFrame.origin.x+_currentColorFrame.size.width+10.0f, textCenter - textHeight) withAttributes:@{NSFontAttributeName: [UIFont boldSystemFontOfSize:12.0f]}]; 428 | [[NSString stringWithFormat:@"G:%3d%%",(int)(currentRgbColor.g*100)] drawAtPoint:CGPointMake(_currentColorFrame.origin.x+_currentColorFrame.size.width+10.0f, textCenter) withAttributes:@{NSFontAttributeName: [UIFont boldSystemFontOfSize:12.0f]}]; 429 | [[NSString stringWithFormat:@"B:%3d%%",(int)(currentRgbColor.b*100)] drawAtPoint:CGPointMake(_currentColorFrame.origin.x+_currentColorFrame.size.width+10.0f, textCenter + textHeight) withAttributes:@{NSFontAttributeName: [UIFont boldSystemFontOfSize:12.0f]}]; 430 | } 431 | 432 | 433 | ///////////////////////////////////////////////////////////////////////////// 434 | // 435 | // 入力 436 | // 437 | ///////////////////////////////////////////////////////////////////////////// 438 | 439 | - (void)clearInput{ 440 | _isTapStart = FALSE; 441 | _isTapped = FALSE; 442 | _isDragStart = FALSE; 443 | _isDragEnd = FALSE; 444 | } 445 | 446 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 447 | if ([touches count] == 1) { 448 | UITouch* touch = [touches anyObject]; 449 | [self setCurrentTouchPointInView:touch]; 450 | _wasDragStart = TRUE; 451 | _isTapStart = TRUE; 452 | _touchStartPosition.x = _activeTouchPosition.x; 453 | _touchStartPosition.y = _activeTouchPosition.y; 454 | [self update]; 455 | } 456 | } 457 | 458 | -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ 459 | UITouch* touch = [touches anyObject]; 460 | if ([touch tapCount] == 1) { 461 | _isDragging = TRUE; 462 | if (_wasDragStart) { 463 | _wasDragStart = FALSE; 464 | _isDragStart = TRUE; 465 | } 466 | [self setCurrentTouchPointInView:[touches anyObject]]; 467 | [self update]; 468 | } 469 | } 470 | 471 | -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 472 | UITouch* touch = [touches anyObject]; 473 | 474 | if (_isDragging) { 475 | _isDragEnd = TRUE; 476 | }else{ 477 | if ([touch tapCount] == 1) { 478 | _isTapped = TRUE; 479 | } 480 | } 481 | _isDragging = FALSE; 482 | [self setCurrentTouchPointInView:touch]; 483 | [self update]; 484 | [NSTimer scheduledTimerWithTimeInterval:1.0/20.0 target:self selector:@selector(setNeedsDisplay15FPS) userInfo:nil repeats:FALSE]; 485 | } 486 | 487 | - (void)setCurrentTouchPointInView:(UITouch *)touch{ 488 | CGPoint point; 489 | point = [touch locationInView:self]; 490 | _activeTouchPosition.x = point.x; 491 | _activeTouchPosition.y = point.y; 492 | } 493 | 494 | - (void)setDelegate:(NSObject*)picker_delegate{ 495 | delegate = picker_delegate; 496 | _delegateHasSELColorWasChanged = FALSE; 497 | // 微妙に重いのでメソッドを持っているかどうかの判定をキャッシュ 498 | if ([delegate respondsToSelector:@selector(colorWasChanged:)]) { 499 | _delegateHasSELColorWasChanged = TRUE; 500 | } 501 | } 502 | 503 | - (void)BeforeDealloc{ 504 | // 何も実行しません 505 | } 506 | 507 | 508 | - (void)dealloc{ 509 | CGImageRelease(_brightnessPickerShadowImage); 510 | } 511 | 512 | @end 513 | --------------------------------------------------------------------------------