Today I haven’t learned something: I haven’t learned a good strategy to write a better rich-text-editing experience for Library Notes and other projects of mine.
Doing syntax-highlighting-as-you-type for plain text content has a lot of advantages, but it is pretty geeky. I’m trying to figure out what’s involved with building a full-on rich text editor instead: One where you make text bold by applying a “bold” attribute to existing text rather than adding
**bold** delimiters to the text.
Where I’m currently stuck is figuring out how I’m supposed to handle lists. What I want are lists that behave like best-in-class rich text editors:
- Bulleted and numbers lists have a hanging indent
- The text input caret doesn’t ever land in the list delimiter. In other words, if the caret is at the start of one element in the list and you try to move the caret to the left, the caret will move to the last character in the previous list entry rather than somewhere in the list delimiter.
- I want this to work in UIKit (
Things I’ve investigated:
- Use an
NSParagraphStyleattribute for an attributed string. However, this doesn’t render anything on a
UITextViewthat is using TextKit 1. For a
UITextViewthat uses TextKit 2, it will render list delimtiers as expected. However, the experience of moving the caret through the document becomes really buggy. TextKit 2 currently has a reputation of being buggy, so I don’t want to waste more time here.
- I’ve tried overriding
position(from:offset:)to see if I can “skip” positions that would land inside the list delimiters. However, while this method gets called as I expect (on Catalyst, anyway), it’s not preventing the caret from landing inside the list delimiter.
- Do all of this in the layout manager, somehow. I currently have a custom layout manager in Library Notes to handle rendering quotes, but I’m not sure how I can use a layout manager to display list delimiters when they’re not present in the text.
There’s remarkably little info about how to make lists work in
UITextView on the internet. So, time to do some Rubber Duck Debugging and then take a break.