当覆盖scrollWheel函数

时间:2015-07-02 13:48:44

标签: macos swift mouse nsscrollview nsevent

当我在NSScrollView中覆盖scrollWheel(theEvent:NSEvent)函数时,我遇到了一个奇怪的错误。

这是我的代码:

import Cocoa

class GraphScrollView: NSScrollView {
    var axisScrollViewInstance: AxisScrollView?

    override func scrollWheel(theEvent: NSEvent) {
        if theEvent.deltaY != 0 {
            axisScrollViewInstance?.scrollEventFromOtherScrollView(theEvent)
            super.scrollWheel(theEvent)
        } else if theEvent.deltaX != 0 {
            super.scrollWheel(theEvent)
        }
    }
}

class AxisScrollView: NSScrollView {
    var graphScrollViewInstance: GraphScrollView?
    override func scrollWheel(theEvent: NSEvent) {
        if theEvent.deltaY != 0 {
            super.scrollWheel(theEvent)
            graphScrollViewInstance?.scrollWheel(theEvent)
        }
    }

    func scrollEventFromOtherScrollView(theEvent: NSEvent) {
        if theEvent.deltaY != 0 {
            super.scrollWheel(theEvent)
        }
    }   
}

代码基本上检查用户滚动的方向,如果方向是垂直的,则将NSEvent转发到另一个NSScrollView。我需要这个,以便我可以有两个NSScrollViews彼此相邻,它们都垂直滚动,其中一个也水平滚动。作为示例,您可以查看Mac日历应用程序,其左侧有一个小时列,仅垂直滚动,右侧有一周概览,可以水平和垂直滚动。

但是,如果我覆盖scrollWheel方法并从内部调用超级函数,则会导致Mighty Mouse出现奇怪的问题。我只能向上和向右滚动,而如果我向任何其他方向滚动它什么都不做,虽然NSEvent总是在发生,忽略我滚动的方向。过了一会儿,它会完全停止滚动。

我已经尝试过简单地覆盖scrollWheel方法,只用这样的事件调用super函数:

override func scrollWheel(theEvent: NSEvent) {
    super.scrollWheel(theEvent)
}

但它会导致同样的问题。我有一个第二个(非Apple)鼠标连接到我的系统,它有一个正常的'滚轮和我的代码完美地工作。

你知道问题可能是什么吗?我听说NSEvents属于不同的子类型(1:Apple Device,0:任何其他设备)。也许这与它有关? 否则,你知道如何让两个同时相邻的NSScrollViews垂直滚动吗?

1 个答案:

答案 0 :(得分:1)

好的,这是Xcode 6.4中的Interface Builder的错误,也可能是早期版本的错误。您必须确保选中NSScrollView的Attribute Inspector中的“Show Vertical Scroller”和“Show Horizo​​ntal Scroller”框。

How the attribute inspector should look like

如果选中这两个框,则不会有覆盖scrollWheel(theEvent:NSEvent)函数的问题。然后,您可以通过将hasHorizontalScrollerhasVerticalScroller设置为false来再次以编程方式删除滚动条而不会出现问题。你的init()


2015年10月12日更新
我已向Apple报告了“bug”,但似乎通过覆盖-scrollWheel函数,该视图失去了响应式滚动功能。

这是Apple开发团队的答案:

  1. 如果覆盖-scrollWheel,则该scrollView无法执行responsiveScrolling。
  2. 如果未启用响应式滚动,则必须显示滚动条才能滚动滚动。
  3. 请参阅+isCompatibleWithResponsiveScrolling
  4. 的文档

    在文档中说:

      

    此方法的默认实现返回true,除非该类重写lockFocus或scrollWheel:方法