How to pass the contents of an NSTextView so that my tabs are drawn with a width of 4 characters

I work with NSTextView, and one of the requirements that I have is that the tab character '\ t' should have the same width as four spaces.

So, the text content will look like this:

AAAA AAAA - 1 tab AAAA - 4 spaces 

And here is how I do it:

 // done when NSTextView first loaded and when // delegate 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 you to display the corresponding layout with the source text, as well as keep the input attributes the same.

The problem is that the end user can change the font. And when that happens, the sample text will be biased. Very similar to the following:

 [smaller font] AAAA AAAA - 1 tab AAAA - 4 spaces 


 [larger font] AAAA AAAA - 1 tab AAAA - 4 spaces 

I tried calling myTextView setNeedsDisplay: YES when I read that it was calling NSTextView setNeedsDisplayInRect: avoidAdditionalLayout with NO for the avoidAdditionalLayout parameter. It didn’t change anything.

I tried calling my call to updateMyTextViewTextAttributes when myTextView has a new set of myFont. This does not change anything.

I also tried passing the layoutManager myTextView to provide a LayoutForTextContainer for the textContainer myTextView. Without changes.

At this moment, I'm not sure what to do next. Any suggestions?

+6
objective-c fonts cocoa appkit
source share
2 answers

Apple's Douglas Davidson provided me with tips to get a response through the cocoa -dev@apple.lists.com list.

I solved the problem by updating the updateMyTextViewTextAttributes function as follows:

 - (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]; /** ADDED CODE BELOW **/  NSRange rangeOfChange = NSMakeRange(0, [[myTextView string] length]);  [myTextView shouldChangeTextInRange:rangeOfChange replacementString:nil];  [[myTextView textStorage] setAttributes:typingAttributes range:rangeOfChange];  [myTextView didChangeText]; [paragraphStyle release]; [typingAttributes release]; } 
+3
source share

Have you tried to calculate the space advance using advancementForGlyph: directly on the font instead of the screen font?

 float charWidth = [myFont advancementForGlyph:(NSGlyph) ' '].width; 

The screen font is not intended to be used directly outside the server window:

Screen fonts are intended for direct use with a windowed server only. Never use them with Application Kit objects, such as in setFont: methods. Inside, the Application Kit automatically uses the appropriate on-screen font for the font object until the view is rotated or scaled.

+1
source share

All Articles