我试图更好地了解它的用法,以提高 OSX 的滚动性能。更具体地说,我试图消除屏幕侧面的“闪烁/闪烁”,因为您快速滚动并且 AppKit 遇到您的视图的非过度绘制(未准备)部分或您的视图部分准备不正确仅限背景。
我的理解是preparedContentRect 代表滚动视图的过度绘制部分-可用于响应式滚动的区域。
第一部分
preparedContentInRect
我在两个子视图中放置了代码NSScrollView
- 每个子视图都是浮动子视图,NSScrollView
它们在滚动时的行为与 documentViews 相同。
在程序启动后(如预期的preparedContentInRect
那样)被调用了几次。然后我滚动到准备区域的末尾,但是(出乎意料地)它没有被再次调用,因为我越来越接近,甚至在准备区域的边缘。为什么不?即使没有用户与 UI 交互(系统空闲),它也不会调用preparedContentInRect
动态扩大过度绘制区域。
第二部分
因为(如上所述)我不能preparedContentInRect
在需要时依赖 AppKit 调用;我重新组织了我的代码以准备preparedContentRect
来自剪辑视图的每个通知boundsChangeNotification
,然后prepareContentInRect
手动调用以通知 AppKit 新的透支区域。
我已经包含了一个“手动”标志,以便我的自定义覆盖可以区分我对 AppKit 的手动调用prepareContentInRect
和内部调用 - 以免让 AppKit 搞砸透支!!!
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)
}
不幸的是,即使prepareContentRect
正在报告我打算准备的矩形,当它滚动时它似乎并没有按照我的预期准备矩形 - 它准备了一个 3,500 点宽而不是 5,040 点宽的矩形,因此我在等待时遇到了可怕的背景颜色用于渲染视图的其余部分。
视图唯一没有得到正确过度绘制的“特殊”事情是它有很多子视图已经使用canDrawSubviewsIntoLayer
.
prepareContentInRect
关于透支,我在上面有什么误解?为什么 AppKit 的行为如此?