Why does an NSTextField leave artifacts over an NSTableView when scrolling through a table?

I want to put a text label on top of the scroll table, but the label conflicts with the scroll pattern. Here you can see the test in which I intentionally placed the label halfway from the table and scrolled it up, as a result of which that part of the labeling was dragged below until it exited the window.

scrolling up breaks label overlay

Also, when I go to the other end of the table and scroll down, sometimes the shortcut seems to redraw, and pieces of it grow along with the scroll:

scrolling down is bad too

scrolling down is bad too

It seems that the table redraws its contents and does not notify other view objects in order to redraw itself if they are superimposed. How can i solve this? This actually seems very related to how to place an NSButton over an NSTableView , which seems to have the same problem, but with a button instead of a label.

+2
source share
4 answers

Another alternative way to get the right redraw is to open the root xib view in the effects inspector and mark its use with Core Animation Layer. This avoids the need to create a custom class using the redraw hook.

+1
source

Do not do this because you will lose a lot of productivity and increase energy consumption.

Try the NSScrollView method - (void)addFloatingSubview:(NSView *)view forAxis:(NSEventGestureAxis)axis

+1
source

This is because in the scroll mode it is configured to copy its contents when scrolling and only redraw the newly opened part as a performance optimization. To disable this, use

 myScrollView.contentView.copiesOnScroll = NO; 

although this will force the scroll to use more CPUs (you can also do this in XIB, see the “copy on scroll” checkbox).

Probably the best approach would be to switch the scroll view and buttons to support the layers:

 myTableView.enclosingScrollView.wantsLayer = YES; myTextView.wantsLayer = YES; 

(Again, you can set this in the Layers inspector of the XIB file, where you can click the checkbox next to each view to give it a layer). Now scrolling will copy only material from its own layer (which no longer includes your text view). In addition, now the entire composition of the text view will be performed using the graphic card. However, if you put text on a transparent background in your own layer, you will lose sub-pixel anti-aliasing. But if it is some other kind (or actually a solid background behind your text), it will look normal.

+1
source

Yes, it seems that NSTableView caches the drawing of the hole table, so the scroll does not need to be updated for each pixel. However, this is exactly what is needed. Fortunately, this can be done, I was able to subclass NSScrollView as follows to add a property and binding to reflectScrolledClipView: ::

 @interface EHScrollView : NSScrollView @property (nonatomic, weak) NSView *refreshView; @end 

The implementation will be as follows:

 #import "EHScrollView.h" @implementation EHScrollView - (void)reflectScrolledClipView:(NSClipView *)aClipView { [super reflectScrolledClipView:aClipView]; [self.refreshView setNeedsDisplay:YES]; } @end 

The only thing needed is to change xib for the user interface. When the table is embedded in the scroll view, select the scroll and modify it to inherit the custom EHScrollView class. Then, in the initialization of the view controller, use the outputs for both the scroll view and the table view, to associate the latter with the former using the refreshView property.

Now, each individual scroll will automatically call setNeedsDisplay: on the refreshView , which means that both the table and everything that is superimposed on top will be redrawn. Of course, this works more intensively than a non-refreshing table, so use it only where it makes sense.

0
source

All Articles