How to replace a text attachment with a custom drawing with NSLayoutManager?
Asked Answered
C

0

5

My ultimate goal is to give the user the ability to split a text inside an NSTextView or UITextView into several sections, where two subsequent sections are visually separated by a custom view separator (possibly, but not necessarily a horizontal rule – I want to be able to adjust the visual appearance of the separator without a hassle).

Example screenshot for section break separators

I need a solution that works on both platforms: macOS and iOS.

(My related question focused on a solution for macOS and there is one that makes use of NSTextAttachmentCells which are not available on iOS.)

My current approach to tackling this problem is the following:

  1. I have a button in the window's toolbar to insert a section break.
  2. When the user taps that button, I create a new attributed string with no text but with a text attachment:

    let attachment = SectionChangeTextAttachment()
    let attachmentString = NSAttributedString(attachment: attachment)
    

    (SectionChangeTextAttachment is a custom subclass of NSTextAttachment that I created in order to be able to distinguish this section break attachment from other possible attachments.)

  3. I insert that attachmentString to text storage at the current cursor position:

    textStorage.insert(attachmentString, at: textView.selectedRange().location)
    
  4. I create a custom NSLayoutManager subclass. Its task is to find all the attachments of class SectionChangeTextAttachment and replace all occurrences with a separator drawing (or glyph?). And here's the problem: With Apple's limited and partially outdated documentation, I cannot figure out how to do this.

So my question is:

How can I make my layout manager replace attachment characters (with a specific attachment) with a custom drawing (of a separator) that takes up more space than the character / glyph?

(I guess there is no glyph for the attachment character and thus the layout manager doesn't provide any space for it.)

Which methods do I need to override in order to make this work?

(Does this approach even make sense to begin with?)

Cuzco answered 15/3, 2019 at 15:8 Comment(2)
I would have gone with a UITableView, with cells as UITextView and headers views (or footer) as custom separator.Entertainment
I thought of that, but the problem is that you cannot select the entire text then — or more specifically you cannot make selections that spread across different sections (which is a requirement for me). And copy & paste gets really difficult as well...Cuzco

© 2022 - 2024 — McMap. All rights reserved.