1

Say I have an NSTextView (or a UITextView on iOS) and I want the user to be able to insert horizontal divider rules, like the HTML <hr> tag or this thing:


What's the best way to implement this?

Apple's documentation is very thing on this. So far, I have two ideas:

  1. Insert an NSTextAttachment for each rule and make the layout manager draw it somehow.

  2. Instead of a single text view, use multiple text views with scrolling disabled, put them in a stack view, add separator views between them and then put the stack view in a scroll view.

Both approaches seem a little wrong or inelegant to me because:

  1. From the documentation, it sounds like text attachments are intended for attaching files in the first place. A horizontal rule is not a file.

  2. If I use multiple text views, I'll probably lose some performance tweaks inherent to NSTextView as all the text views need to be loaded and ready for display, no matter where the user has scrolled. In addition, the multiple text view approach would prevent the user from selecting the entire text, which is a requirement in my app.

Any better ideas?

Mischa
  • 15,816
  • 8
  • 59
  • 117

1 Answers1

2

I remember trying to do this years ago. Using NSTextAttachment was the method that worked for me. I bookmarked this conversation with Mike Ferris to help me remember how to do it. I don't have the code anymore, but it was pretty straightforward. I subclassed NSTextAttachmentCell which conforms to NSTextAttachmentCellProtocol. You override cellFrame(for textContainer: NSTextContainer, proposedLineFragment lineFrag: NSRect, glyphPosition position: NSPoint, characterIndex charIndex: Int) which gives you access to its container that can provide its width, and it has the line fragment which gives you the y position of the text above your divider (plus any padding you want). Then just override the draw(withFrame cellFrame: NSRect, in controlView: NSView?) method and draw your divider.

As for the payload NSData, you could do anything with that. Maybe you include the width of the line, it's padding, color, etc? The good thing about using NSTextAttachment is that it stays embedded in the text itself like the <hr> tag.

smr
  • 890
  • 7
  • 25
  • That's a great answer, and the link you posted that leads to the conversation which dates back to 2002 turns out to be very helpful as well. Unfortunately, this solution doesn't work for iOS. iOS does support text attachments, but it doesn't support text attachment _cells_ which are key to the suggested solution. I'm now trying to find a way to use text attachments as "markers" that the layout manager understands and then transforms into a visual separator – but that seems to be a very tricky task, mainly due to the lack of documentation. – Mischa Mar 15 '19 at 14:11
  • FYI: I asked a [second question](https://stackoverflow.com/q/55185556/2062785) to address the issue on iOS as well. – Mischa Mar 15 '19 at 15:12