NSScrollView:使用CMD +滚动交互放大并保留响应式滚动

问题描述 投票:2回答:1

在Mavericks中,Apple在NSScrollView中引入了响应式滚动架构。此功能添加了一种智能方法,用于生成透支,并将传入滚动事件的处理从主事件循环解耦为单独的事件循环。 in the session 215 from WWDC 2013详细介绍了该主题。

由于事件模型不同,滚动事件不再通过scrollWheel(with:)方法。实际上,如果在NSScrollView子类中重写此方法,则完全退出响应式滚动体系结构并退回到传统模型。

在我的NSScrollView中,我想在按住命令键的同时使用滚动实现放大的交互。这可以在MindNode或OmniGraffle应用程序中观察到。执行此操作的标准方法是覆盖scrollWheel(with:)并检查每个滚动事件上的modifierFlags。如上所述,这将导致从响应滚动模型退出。

我想知道是否有一种方法来实现这种交互,同时还保留响应式滚动?


我已经实现/尝试过的内容:

  • 在我的NSScrollView子类中,我已经覆盖了scrollWheel(with:),并从静态属性true返回isCompatibleWithResponsiveScrolling,以强制参与响应式滚动。
  • 这样我就可以检查修改器标志的第一个滚动事件。如果未按下命令键,我只需将事件传递给super并让NSScrollView执行其操作。如果按下命令键,我会转到不同的路径并跟踪窗口上的下一个滚动事件以进行放大。
  • 问题是当其中一个跟踪循环正在运行并且用户更改了命令键的按下状态(按下或释放它)。
  • 从放大到滚动(在命令键释放时)的切换很简单,因为跟踪循环完全在我的控制之下。
  • 从滚动切换到放大(按下命令键)更加棘手,因为我无法检查滚动事件。我已经覆盖了flagsChanged(with:)并且可以观察到这一刻何时发生,但我还没有找到一种方法来结束滚动。 This SO question询问有关结束/禁用滚动但尚未回答的问题。
objective-c cocoa appkit nsscrollview nsevent
1个回答
0
投票

我将在这里回答,而不是在评论中,因为我有更多的数据。

“响应式滚动”有两个问题:

(1)几年前出现了一个错误 - 加速响应滚动与传统滚动的区别。通过加速我的意思是文件在轨迹板上任意给定的移动量移动的距离 - 传统的滚动没有移动文件那么多,所以感觉迟钝。我报告了这个,似乎至少在10.14中得到了解决。

⑵尽管我可以从我的研究中得知,并且与Apple人交谈,“响应式滚动”旨在使滚动更加一致,即使应用程序占用主线程(通常会阻止事件流) - 它处理滚轮而不是在后台线程上的事件,然后用它们向主线程发送消息。因为这仍然涉及每个滚动事件调用的主线程(或滚动事件被合并)我不清楚这是什么情况这是一个胜利。可能有一些额外的魔术,其中scrollview将从缓存中绘制更多的文档你实现了可选的缓存内容。

在我的应用程序中,我实际上使用了带有虚拟(透明)文档的scrollview,我将其滚动事件和SceneKit相机移动。由于我在滚动时场景发生了巨大变化,因此尝试在可见矩形之外进行预渲染没有任何好处。

所以在我的情况下,我不再感觉到响应和传统滚动之间的任何性能差异(尽管我在提交错误时回复了)。

© www.soinside.com 2019 - 2024. All rights reserved.