I'm working with an NSTextView and one of the requirements I have is that a tab character, '\t', shall have the same width as four spaces.
So the text-content would look like this:
AAAA
AAAA - 1 tab
AAAA - 4 spaces
And this is how I accomplish this:
// done when NSTextView first loaded and when
// delegate's textDidBeginEditing gets called: (perhaps overkill, but is a work in progress).
- (void)updateMyTextViewTextAttributes
{
NSMutableParagraphStyle* paragraphStyle = [[myTextView defaultParagraphStyle] mutableCopy];
if (paragraphStyle == nil) {
paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
}
float charWidth = [[myFont screenFontWithRenderingMode:NSFontDefaultRenderingMode] advancementForGlyph:(NSGlyph) ' '].width;
[paragraphStyle setDefaultTabInterval:(charWidth * 4)];
[paragraphStyle setTabStops:[NSArray array]];
[myTextView setDefaultParagraphStyle:paragraphStyle];
NSMutableDictionary* typingAttributes = [[myTextView typingAttributes] mutableCopy];
[typingAttributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
[typingAttributes setObject:scriptFont forKey:NSFontAttributeName];
[myTextView setTypingAttributes:typingAttributes];
}
This allows the appropriate layout to be shown with the initial text as well as keep the typing attributes the same.
The problem is that the end-user can change the font. And when that happens, the sample text becomes misaligned. Much like the below:
[smaller font]
AAAA
AAAA - 1 tab
AAAA - 4 spaces
[larger font]
AAAA
AAAA - 1 tab
AAAA - 4 spaces
I've tried calling myTextView's setNeedsDisplay:YES as I read that it ends up calling NSTextView's setNeedsDisplayInRect:avoidAdditionalLayout with a NO for the avoidAdditionalLayout parameter. This didn't change anything.
I've tried calling my updateMyTextViewTextAttributes call when myTextView has the new myFont set. That doesn't change a thing.
I've also tried telling the layoutManager of myTextView to ensureLayoutFOrTextContainer for the textContainer of myTextView. No change.
At this point, I'm not sure what to try next. Any suggestions?