diff --git a/Aztec/Classes/TextKit/LayoutManager.swift b/Aztec/Classes/TextKit/LayoutManager.swift index 772aa7d23..06d4011af 100644 --- a/Aztec/Classes/TextKit/LayoutManager.swift +++ b/Aztec/Classes/TextKit/LayoutManager.swift @@ -27,6 +27,9 @@ class LayoutManager: NSLayoutManager { /// var blockquoteBorderWidth: CGFloat = 2 + /// The list indent style + /// + var listIndentStyle: TextList.IndentStyle = .default /// Draws the background, associated to a given Text Range /// @@ -213,15 +216,16 @@ private extension LayoutManager { } let characterRange = self.characterRange(forGlyphRange: glyphsToShow, actualGlyphRange: nil) + var firstLevelWidth: CGFloat? textStorage.enumerateParagraphRanges(spanning: characterRange) { (range, enclosingRange) in - guard textStorage.string.isStartOfNewLine(atUTF16Offset: enclosingRange.location), let paragraphStyle = textStorage.attribute(.paragraphStyle, at: enclosingRange.location, effectiveRange: nil) as? ParagraphStyle, let list = paragraphStyle.lists.last else { return } + let attributes = textStorage.attributes(at: enclosingRange.location, effectiveRange: nil) let glyphRange = self.glyphRange(forCharacterRange: enclosingRange, actualCharacterRange: nil) let markerRect = rectForItem(range: glyphRange, origin: origin, paragraphStyle: paragraphStyle) @@ -233,8 +237,24 @@ private extension LayoutManager { start = textStorage.numberOfItems(in: list, at: enclosingRange.location) } } + + var indentLevel = 1 + // Determine indentation level, if needed. The indentation level is only used by the standard list style + if list.style == .unordered, listIndentStyle == .standard { + // only get the width of the first level once + if firstLevelWidth == nil { + firstLevelWidth = paragraphStyle.indentToFirst(TextList.self) + } + + // calculate current indent level + let indentWidth = paragraphStyle.indentToLast(TextList.self) + if let firstLevelWidth = firstLevelWidth { + indentLevel = Int(indentWidth / firstLevelWidth) + } + } + markerNumber += start - let markerString = list.style.markerText(forItemNumber: markerNumber) + let markerString = list.style.markerText(forItemNumber: markerNumber, indentLevel: indentLevel) drawItem(markerString, in: markerRect, styled: attributes, at: enclosingRange.location) } } diff --git a/Aztec/Classes/TextKit/ParagraphProperty/TextList.swift b/Aztec/Classes/TextKit/ParagraphProperty/TextList.swift index a2cf28306..1c9252977 100644 --- a/Aztec/Classes/TextKit/ParagraphProperty/TextList.swift +++ b/Aztec/Classes/TextKit/ParagraphProperty/TextList.swift @@ -14,14 +14,32 @@ open class TextList: ParagraphProperty { case ordered case unordered - func markerText(forItemNumber number: Int) -> String { + func markerText(forItemNumber number: Int, indentLevel: Int = 1) -> String { switch self { - case .ordered: return "\(number)." - case .unordered: return "\u{2022}" + case .ordered: + return "\(number)." + case .unordered: + switch indentLevel { + case 1: + return "\u{2022}" + case 2: + return "\u{2E30}" + default: + return "\u{2B29}" + } } } } + /// List Indent Styles + /// + public enum IndentStyle: Int { + /// A default single bullet style for each indentation level + case `default` + /// The standard bullet styles for each indentation level (i.e., HTML style) + case standard + } + public let reversed: Bool public let start: Int? diff --git a/Aztec/Classes/TextKit/TextView.swift b/Aztec/Classes/TextKit/TextView.swift index e4e0404bf..a543fcba6 100644 --- a/Aztec/Classes/TextKit/TextView.swift +++ b/Aztec/Classes/TextKit/TextView.swift @@ -228,6 +228,17 @@ open class TextView: UITextView { var maximumListIndentationLevels = 7 + /// The list indent style + /// Default is `default`, single style for each level. + public var listIndentStyle: TextList.IndentStyle { + get { + return layout.listIndentStyle + } + set { + layout.listIndentStyle = newValue + } + } + // MARK: - Properties: Blockquotes /// The max levels of quote indentation allowed diff --git a/Example/Example/EditorDemoController.swift b/Example/Example/EditorDemoController.swift index 016a0cb5f..dc567222d 100644 --- a/Example/Example/EditorDemoController.swift +++ b/Example/Example/EditorDemoController.swift @@ -174,6 +174,7 @@ class EditorDemoController: UIViewController { view.addSubview(separatorView) editorView.richTextView.textContainer.lineFragmentPadding = 0 + editorView.richTextView.listIndentStyle = .standard // color setup if #available(iOS 13.0, *) { view.backgroundColor = UIColor.systemBackground