3

我试图更好地了解它的用法,以提高 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 的行为如此?

4

0 回答 0