I am trying to understand its usage better in order to improve scrolling performance on OSX. More specifically, I am trying to eradicate the "flashing/flickering" on the side of the screen as you scroll fast and AppKit runs into non-overdrawn (non-prepared) portions of your view OR portions of your view that have been prepared incorrectly with background-only.
My understanding is that the preparedContentRect represents the overdrawn section of your scrollview - the area available for responsive scrolling.
Part One
I placed code within the preparedContentInRect
for two subViews of NSScrollView
- each are floating subViews of NSScrollView
which behave the same as documentViews when scrolling.
The preparedContentInRect
gets called several times just after program launch (as expected). I then scroll to the end of the prepared area BUT (unexpectedly) it doesn't get called again as I get nearer and nearer and even on the edge of the prepared area. Why not? Even with no user interaction with the UI (system idle) it does not call preparedContentInRect
to enlarge the overdraw area dynamically.
Part Two
Since (as above) I could not rely on AppKit calling preparedContentInRect
when needed; I reorganised my code to prepare the preparedContentRect
after each notification from the clipview's boundsChangeNotification
and then call prepareContentInRect
manually to inform AppKit of the new overdraw area.
I have included a "manual" flag so that my custom override can differentiate between my manual calls to prepareContentInRect
and internal calls from AppKit - so as not to let AppKit mess up the overdraw!!!
var manuallyPrepareContentInRect = false
override func prepareContentInRect(rect: NSRect) {
if manuallyPrepareContentInRect{
println("GRID manual prepareContentInRect call: \(rect)")
manuallyPrepareContentInRect = false
super.prepareContentInRect(rect)
return
}
println("GRID bypass AppKit prepareContentInRect call: \(self.preparedContentRect)")
super.prepareContentInRect(self.preparedContentRect)
}
Unfortunately, even though prepareContentRect
is reporting my intended prepare rect, when it scrolls it does not seem to have prepared the rect as I have intended - it prepares a rect 3,500 points wide instead of 5,040 wide and hence I run into the dreaded background color while waiting for the rest of the view to render.
The only "special" thing about the view that isn't getting correct overdraw is that it has a whole lot of subviews that have been drawn into its layer using canDrawSubviewsIntoLayer
.
What am I misunderstanding above with respect to prepareContentInRect
and overdraw? Why is AppKit behaving like it is?