NSTextView Contents Disappear When Ruler shown

I have a problem with rulers in an NSTextView. My code has worked fine from about Sierra (10.12), up to Ventura (13), it stopped working in Sonoma and continues to fail in the same way in Sequoia (14 - 15). When I display the ruler, the contents of the text area disappears leaving just a pale grey background. When I make the ruler invisible again the text reappears.

No errors are reported (at compile or run time). I have tried adding refreshes of the text view in various places with no result. I have (for Sequoia) used Interface Builder to force the text view to use TextKit 1, also with no success. I’m at a loss as to how to proceed because I’m not getting any diagnostics, simply changed behaviour.

My app provides a programming IDE. It includes a program editor that uses line numbering code for an NSTextView from WWDC/Noodlesoft. The line numbers are shown in the ruler which is sometimes visible and sometimes not. When I display the ruler, I also set the main text to not editable but removing this setting does not appear to make any difference.

Any suggestions would be very wel

PLATFORM AND VERSION macOS, Objective C Development environment: Xcode Version 16.0 (16A242d) [and previously Xcode 15], macOS All releases of Sonoma and Sequoia 15.0.1 (24A348) Run-time configuration: macOS Sequoia 15.0.1 (24A348)

The sequence is essentially: [editTextView setEditable:NO]; [self showRulerIn:editTextView visible:YES];

Using:

-(void)showRulerIn:(NSTextView*)editorTv visible:(BOOL)vis {
NSScrollView *scrollV = [editorTv enclosingScrollView];
NSClipView *clipV = [scrollV contentView];
MBEditorTextView *textView = (MBEditorTextView*)[scrollV documentView];	// The actual text

[scrollV setRulersVisible:vis];								// Creates the ruler if necessary
…
return; }

LINE NUMBERING CODE The line number code comes from 2 sources but they are so similar that one must be derived from the other: Apple’s WWDC 2010 code at: https://download.developer.apple.com/videos/wwdc_2010__hd/session_114__advanced_cocoa_text_tips_and_tricks.mov

Noodlesoft's code at: https://www.noodlesoft.com/blog/2008/10/05/displaying-line-numbers-with-nstextview/

Answered by Command_F in 812742022

Thank you, your first "guess" solves the problem - excellent!

For anyone using the Noodlesoft version, the actual code I've added is related to the creation of the NoodleLineNumberView using initWithScrollView:(NSScrollView *)aScrollView. After sending that, I just tweak the custom view as suggested; this is also backwards-compatible which is helpful (at least to me).

Note that the line numbers actually live in a vertical ruler.

lineNumberView = [[NoodleLineNumberView alloc] initWithScrollView:scrollView];

[scrollView setVerticalRulerView:lineNumberView];
[scrollView setHasVerticalRuler:YES];
[[scrollView verticalRulerView] setClipsToBounds:YES];	// This defaults to NO as of macOS 14 (Sonoma), we need YES to contain its drawing

// etc

This seems to be a complete fix.

I don't remember seeing the AppKit Release Notes, they're very useful although I may not have made the connection without some help. Hopefully there will be some along soon for macOS 15.

Thanks again to Ziqiao Chen for the help.

This is likely related to the change on NSView’s clipsToBounds, as described in the NSView section of AppKit Release Notes for macOS 14.

My best guess is that you have a custom ruler view to show the line numbers, and due to the change on clipsToBounds, your custom view convers the text view content. In that case, you can fix the issue by setting the custom ruler view’s clipsToBounds to true:

scrollView.horizontalRulerView = [[CustomRulerView alloc] initWithScrollView:scrollView  orientation:NSHorizontalRuler];
scrollView.horizontalRulerView.clipsToBounds = YES;

Or if you use the dirtyRect to draw your content, try to replace it with self.bounds:

@implementation CustomRulerView
- (void)drawRect:(NSRect)dirtyRect {
    //[super drawRect:dirtyRect];
    [super drawRect:self.bounds];
    // Drawing code here.
}
@end

If my guess is bad, you might want to share more implementation details, ideally a focused sample project that demonstrates the issue, for folks to take a look.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Accepted Answer

Thank you, your first "guess" solves the problem - excellent!

For anyone using the Noodlesoft version, the actual code I've added is related to the creation of the NoodleLineNumberView using initWithScrollView:(NSScrollView *)aScrollView. After sending that, I just tweak the custom view as suggested; this is also backwards-compatible which is helpful (at least to me).

Note that the line numbers actually live in a vertical ruler.

lineNumberView = [[NoodleLineNumberView alloc] initWithScrollView:scrollView];

[scrollView setVerticalRulerView:lineNumberView];
[scrollView setHasVerticalRuler:YES];
[[scrollView verticalRulerView] setClipsToBounds:YES];	// This defaults to NO as of macOS 14 (Sonoma), we need YES to contain its drawing

// etc

This seems to be a complete fix.

I don't remember seeing the AppKit Release Notes, they're very useful although I may not have made the connection without some help. Hopefully there will be some along soon for macOS 15.

Thanks again to Ziqiao Chen for the help.

NSTextView Contents Disappear When Ruler shown
 
 
Q