subconsciousnetwork / subconscious

Apache License 2.0
8 stars 0 forks source link

Swipe typing not functioning correctly #211

Closed gordonbrander closed 2 years ago

gordonbrander commented 2 years ago

Reported by Ade and Dietrich.

I think this is a side-effect of re-rendering the text with every keystroke in https://developer.apple.com/documentation/uikit/uitextviewdelegate/1618599-textviewdidchange. Aka, we thrash the text.

gordonbrander commented 2 years ago

One quick thing to try could be to clear and set the attributes of the editor NSAttributedString, rather than creating and setting a new NSAttributedString.

gordonbrander commented 2 years ago

Prior art to investigate https://github.com/tophat/RichTextView

gordonbrander commented 2 years ago

More prior art: https://github.com/rajdeep/proton/

It looks like they use the textstorage API of UITextView https://github.com/rajdeep/proton/blob/64bd132cac3bce2b3e6d6ebe065490dea4eac6ab/Proton/Sources/Swift/Core/RichTextView.swift#L445

The text storage object holding the text that displays in the text view https://developer.apple.com/documentation/uikit/uitextview/1618611-textstorage

TextStorage API https://developer.apple.com/library/archive/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/CustomTextProcessing/CustomTextProcessing.html

gordonbrander commented 2 years ago

Promising tutorial on TextKit / TextStorage.

Example of bolding asterisks https://www.raywenderlich.com/5960-text-kit-tutorial-getting-started#toc-anchor-013

override func processEditing() {
  performReplacementsForRange(changedRange: editedRange)
  super.processEditing()
}

processEditing() sends notifications to the layout manager when the text changes. It also serves as a convenient home for any post-editing logic. https://developer.apple.com/documentation/appkit/nstextstorage/1525980-processediting

gordonbrander commented 2 years ago

After digging into https://github.com/gordonbrander/subconscious/issues/211#issuecomment-1068653655 further, I think TextStorage is likely to be the solution. It's a lower-level API that seems to be designed for the kind of per-edit attribute changes that we want to do.

Notes here: https://github.com/gordonbrander/subconscious/wiki/TextKit