【问题标题】:Scrolling in NSScrollView stops when overwriting scrollWheel function覆盖 scrollWheel 函数时,NSScrollView 中的滚动停止
【发布时间】:2015-09-20 02:13:21
【问题描述】:

当我在 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。我需要这个,以便我可以有两个相邻的 NSScrollView,它们都垂直滚动,其中一个也水平滚动。例如,您可以查看 Mac 日历应用程序,该应用程序的左侧有一个小时列,仅垂直滚动,右侧有一个水平和垂直滚动的周概览。

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

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

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

但它会导致同样的问题。我有第二个(非 Apple)鼠标连接到我的系统,它有一个“普通”滚轮,我的代码可以正常工作。

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

【问题讨论】:

    标签: macos swift mouse nsscrollview nsevent


    【解决方案1】:

    好的,这是 Xcode 6.4 中的 Interface Builder 的一个错误,可能在早期版本中也是如此。您必须确保选中 NSScrollView 的属性检查器中的“显示垂直滚动条”和“显示水平滚动条”框。

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


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

    这是苹果开发团队的回答:

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

    在文档中说:

    该方法的默认实现返回true,除非该类覆盖了lockFocus或scrollWheel:方法

    【讨论】:

    • 非常感谢@Peter 的这个帖子。我们面临同样的问题。
    【解决方案2】:

    我遇到了同样的问题,需要水平滚动覆盖,似乎可行的是:

    override func scrollWheel(with event: NSEvent) {
        self.hasHorizontalScroller = true
        self.hasVerticalScroller = true
    
        // do your magic here
    
        self.hasHorizontalScroller = false
        self.hasVerticalScroller = false
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      • 1970-01-01
      • 2016-04-27
      • 2018-06-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多