Skip to content

diondurigon-fb/RichTextEditor

Repository files navigation

RichTextEditor

About RichTextEditor

RichTextEditor is a Swift library that provides a UITextView subclass with HTML visual-editing capabilities.

  • Use this library if you want to create an App that interacts with raw HTML content.

Requirements

  • iOS 11 and above
  • Xcode 12.2 and above

Running the Example App

To run the Example app

Usage

After installing RichTextEditor, import the module and use the RichTextEditor.TextView view as shown below:

import RichTextEditor

// ...

let textView = RichTextEditor.TextView(
    defaultFont: UIFont,
    defaultParagraphStyle: ParagraphStyle = ParagraphStyle.default,
    defaultMissingImage: UIImage) {

Architecture

RichTextEditor provides a UI component to display and edit HTML content in a performant way. It does not implement its text layout functionality. Instead, it builds on top of Apple's UITextView provided by the UIKit framework.

The library is composed of two main systems:

  • TextView a user interface component that allows the presentation and editing of the HTML
  • HTML converters that transform raw HTML to NSAttributedString and vice-versa

You can use each of the components separately, but they are all composed under the TextView class to provide a single element to display and edit HTML.

TextView

TextView is the core class of the system. It's a UITextView subclass that implements custom subclasses of NSTextStorage, NSLayoutManager, and NSAttributeString attributes to allow HTML editing.

There are two main tasks that this class handles:

  • Maintenance of the custom NSAttributedString attributes and attachments as the user edits the content to represent a valid HTML string.
  • Presentation of the custom attributes, like lists and quotes

The TextView and TextStorage classes are responsible for the maintenance of the NSAttributedString.

They handle user manipulation of formatting (strong, emphasis, lists, blockquotes), embeds (images, videos, separators), and the user interaction with them (line breaks, composition).

The formatting is implemented by the toggle(formatter, atRange) method in combination with AttributeFormatter objects. The formatter objects are split into the following categories:

For embeds, like images, videos, separators, tables, etc subclasses of the following are used NSTextAttachment object:

The replace(at:NSRange, with: NSTextAttachment) handles the insertion of embeds with multiple helpers methods to handle each specific type of embed.

The attachment objects work by delegating their presentation using the following protocols:

Another essential task is interaction with user input and handling new lines, deleting list items, and indents around:

  • Lists
  • Quote
  • Paragraphs

The following "ensure..." methods handle all these scenarios:

These methods check if you are adding or removing new paragraphs around lists or quotes and update the attributes accordingly.

Presentation of the custom attributes

The LayoutManager class handles the presentation for the custom attributes that the standard NSLayoutManager is unable to do:

  • Backgrounds and vertical bars for Quotes: drawBlockquotes
  • Backgrounds for Pre: drawHTMLPre
  • List bullets: drawLists

The layout manager uses the extra information provided by the ParagraphStyle class to be able to render the correct background and bullets for each element.

HTML Converter

The HTMLConverter class handles all the conversation between HTML and NSAttributedString. The main entry points are:

Converting from HTML to NSAttributedString

Two classes are responsible for the conversion:

The HTMLParser class uses the libXML2 library to read the raw HTML. It then transforms the document returned to a more developer-friendly DOM node tree. The DOM node tree implementation has classes representing elements, text, CSS attributes, CSS values, and comments. AttributedStringSerializer then converts this DOM tree to an NSAttributedString.

The specialized NSAttributedString has custom attributes that add extra information about the HTML elements that the string contains:

  • HTMLRepresentation stores the original HTML elements and attributes that were in the initial HTML
  • ParagraphStyle is a subclass on NSParagraphMutableStyle, that allows representation of a hierarchy of elements, for example, nested lists, blockquote inside lists, and others.

Specialized Converter classes transform from HTML Elements to NSAttributedString text and attributes, for example:

Converting NSAttributedString to HTML

In a mirror process from the HTML to NSAttributed conversion, there are the following classes:

The AttributedStringParser transforms the NSAttributedString to a DOM tree. On a first pass, it iterates paragraph by paragraph and uses StringAttributesConverters and AttachmentConverters to convert from NSStringAttributes and NSAttachments to the DOM. Then it goes through the DOM tree and merges nodes to create a simplified version of the tree.

The HTMLSerializer is used to convert the DOM Tree to an HTML string.

About

RichTextEditor for iOS

Resources

Stars

Watchers

Forks

Packages

No packages published