如何防止在MacOS NSScrollView中垂直滚动时的抖动和水平漂移



在一个用Swift编写的MacOS应用程序中,我有一个香草的子类NSScrollView,它允许放大。它所呈现的documentView不是很宽,完全水平贴合在NSScrollView的显示区域范围内。但是文档很长,所以它是垂直滚动的

当我在触控板上使用两指手势缓慢移动时,NSScrollView阻止任何水平移动(除了一点弹性)。垂直平移也可以正常工作。

当我用力垂直移动(轻轻轻弹)并松开时,该方向的滚动会以虚拟动量持续一段时间,然后减速并停止。再次,一切似乎都是正确的。

不过,有时候,滚动会突然停止,这是基于苹果内部(默认)NSPanGestureRecognizer分析移动的方式有所不同。突然停下来是不想要的,也是令人沮丧的。似乎只有当文档被缩小时才会发生这种情况。放大后,轻击触控板后不会出现抖动。因此,差异可能与手势识别器在屏幕坐标系统中工作有关,而不是NSScrollView的放大坐标系统。

另一个问题是,如果平移手势很强,并且有任何对角线方向(这是大多数时候,因为很难在触控板上完美垂直地轻击),自动连续滚动会漂移文档视图沿对角线方向向左或向右显示,尽管没有必要这样做,而且它通常是水平固定的。对于非常长的连续滚动,文档视图甚至会将完全移到可见边界之外,这有点荒谬。然后,当连续滚动停止时,NSScrollView立即(没有连续滚动)将documentView完全跳回视图(水平)。

同样的漂移也发生在对非常宽而不是非常高的文档进行水平连续滚动时。

在手势完成后的连续滚动过程中,无论是否有居中约束生效,都会发生这种漂移,这是一个lloadthisstackoverflow问题和答案。

所以…有没有办法防止这种抖动和漂移在NSScrollView中连续滚动?

Willeke的建议似乎是正确的。它还解决了抖动问题,原因我不明白。子类NSScrollView现在是:

class MyScrollView : NSScrollView {
override init(frame fr: NSRect)
{
super.init(frame: fr)
prepareScrolling()
}
required init?(coder: NSCoder)
{
super.init(coder: coder)
prepareScrolling()
}
private func prepareScrolling()
{
self.allowsMagnification = true
self.usesPredominantAxisScrolling = true        // <-- Added to fix the problem
self.maxMagnification = 4.0
self.minMagnification = 0.25
}
// Etc.
}

最新更新