7

My goal is to use TextKit to italicize, set the text size, etc. of certain words.

To start, I am only trying to highlight a character in my text string. Being new to TextKit (and truthfully to programming in general), I am following the syntax highlighting topic of obc.io issue #5.

When using the NSLayoutManager built-in to the UITextView I created, my text appears on screen with no thrown exceptions. When I set my UITextView as the layout manager of my NSTextStorage subclass in my view controller (below), I receive errors for an exception for invalid glyph index(s).

_textStorage = [BBRSyntaxHighlightTextStorage new]; 
[_textStorage addLayoutManager: self.readerTextView.layoutManager];

The console output is below:

_NSLayoutTreeLineFragmentRectForGlyphAtIndex invalid glyph index 528
2013-12-01 15:23:24.949 BibleReader[6077:70b] !!! _NSGlyphTreeInvalidateGlyphsForCharacterRange invalid char range 1
2013-12-01 15:23:24.956 BibleReader[6077:70b] !!! _NSLayoutTreeLineFragmentRectForGlyphAtIndex invalid glyph index 528
2013-12-01 15:23:24.957 BibleReader[6077:70b] !!! _NSGlyphTreeInvalidateGlyphsForCharacterRange invalid char range 1
2013-12-01 15:23:24.957 BibleReader[6077:70b] !!! _NSGlyphTreeInvalidateGlyphsForCharacterRange character count mismatch
2013-12-01 15:23:24.958 BibleReader[6077:70b] !!! _NSLayoutTreeLineFragmentRectForGlyphAtIndex invalid glyph index 4040
2013-12-01 15:23:24.959 BibleReader[6077:70b] !!! _NSGlyphTreeInvalidateGlyphsForCharacterRange invalid char range 1

I have read through Apple's Text Programming Guide many times and think I understand how the text system is established, but have no idea why my glyph count would exceed the number of glyphs...

I created gist's for my viewController and NSTextStorage subclass, here and here, respectively.

Jeff Lewis
  • 135
  • 4
  • 11

1 Answers1

11

It looks like your layout manager hasn't been properly removed from its original NSTextStorage object. Call [self.readerTextView.textStorage removeLayoutManager:self.readerTextView.layoutManager] before you add the layout manager to your custom text storage sub class.

In general, I've found TextKit to not play well when mixing nib/xib/storyboard created UITextViews with custom subclasses of the TextKit objects. You can get around some of this by overriding - (id)awakeAfterUsingCoder:(NSCoder *)aDecoder on UITextView and constructing the text system using the classes you want, but normally I'd recommend sticking to in-code custom text system creation.

NSGod
  • 22,699
  • 3
  • 58
  • 66
Ben Lachman
  • 3,083
  • 1
  • 28
  • 44
  • 1
    I was able to get this working without needing to override awakeAfterUsingCoder. Removing the layoutManager prior to adding the initializing the subclassed textStorage and adding the readerTextView's layoutManager solved my problem; the text view renders the text on screen using my custom textStorage. – Jeff Lewis Jan 13 '14 at 02:54
  • 1
    Wow, `removeLayoutManager:` did the trick for me. Thank you so much! – Vadim Mar 31 '15 at 17:26