首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >另一个NSScrollView中的NSScrollView

另一个NSScrollView中的NSScrollView
EN

Stack Overflow用户
提问于 2011-12-24 17:40:06
回答 3查看 2.1K关注 0票数 6

我有一个嵌套在另一个NSScrollview中的NSScrollview。如何使内部视图仅处理水平滚动?垂直滚动应移动外部视图。

目前,我从内部视图将scrollWheel:事件传递给外部视图,但速度非常慢。

EN

回答 3

Stack Overflow用户

发布于 2012-11-29 22:27:47

我还遇到了嵌套滚动视图的问题。内部滚动视图应水平滚动,外部滚动视图应垂直滚动。

当处理来自魔术鼠标/触控板的滚动事件时,为每个手势只选择一个滚动视图是很重要的,否则当你的手指不能完全伸直时,你会看到奇怪的抖动。您还应确保用两个手指轻敲触控板会同时显示两个滚动条。

在处理来自强大的鼠标或使用老式滚轮的鼠标的传统滚动事件时,您必须为每个事件选择正确的滚动视图,因为事件中没有手势阶段信息。

这是我的内部滚动视图的子类,仅在Mountain Lion中测试:

代码语言:javascript
运行
复制
@interface PGEHorizontalScrollView : NSScrollView {
    BOOL currentScrollIsHorizontal;
}
@end

@implementation PGEHorizontalScrollView
-(void)scrollWheel:(NSEvent *)theEvent {
    /* Ensure that both scrollbars are flashed when the user taps trackpad with two fingers */
    if (theEvent.phase==NSEventPhaseMayBegin) {
        [super scrollWheel:theEvent];
        [[self nextResponder] scrollWheel:theEvent];
        return;
    }
    /* Check the scroll direction only at the beginning of a gesture for modern scrolling devices */
    /* Check every event for legacy scrolling devices */
    if (theEvent.phase == NSEventPhaseBegan || (theEvent.phase==NSEventPhaseNone && theEvent.momentumPhase==NSEventPhaseNone)) {
        currentScrollIsHorizontal = fabs(theEvent.scrollingDeltaX) > fabs(theEvent.scrollingDeltaY);
    }
    if ( currentScrollIsHorizontal ) {
        [super scrollWheel:theEvent];
    } else {
        [[self nextResponder] scrollWheel:theEvent];
    }
}
@end

我的实现并不总是正确地转发手势取消事件,但至少在10.8中这不会造成问题。

票数 7
EN

Stack Overflow用户

发布于 2012-07-19 22:10:17

这是我的NSScrollView子类,它可以完成您所要求的任务。由于它只是将事件传递到响应器链上,而不关心这些事件,因此它的性能应该与它不是子类一样好(或者至少是close)

H文件

代码语言:javascript
运行
复制
#import <Cocoa/Cocoa.h>

@interface HorizontalScrollView : NSScrollView

@end

和我

代码语言:javascript
运行
复制
@implementation HorizontalScrollView

- (void)scrollWheel:(NSEvent *)theEvent {
    NSLog(@"%@", theEvent);
    if(theEvent.deltaX !=0)
        [super scrollWheel:theEvent];
    else
        [[self nextResponder] scrollWheel:theEvent];

}
@end
票数 2
EN

Stack Overflow用户

发布于 2018-12-19 17:35:36

Swift 4.

答案是上面Jakob的优秀答案的翻译,增加了一个方向标志。

正如在他回答的评论中提到的,如果这项工作做得不好,可能会出现微妙的复杂情况。当简单地将所有scrollWheel()调用转发给下一个响应器时,我看到了NSTrackingAreas没有正确更新以及NSTextView视图上的工具提示和光标样式未对齐的问题。

代码语言:javascript
运行
复制
class ECGuidedScrollView: NSScrollView
{
    enum ScrollDirection {
        case vertical
        case horizontal
    }

    private var currentScrollMatches: Bool = false
    private var scrollDirection: ScrollDirection

    init(withDirection direction: ScrollDirection) {
        scrollDirection = direction
        super.init(frame: NSRect.zero)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func scrollWheel(with event: NSEvent)
    {        
        // Ensure that both scrollbars are flashed when the user taps trackpad with two fingers
        if event.phase == .mayBegin {
            super.scrollWheel(with: event)
            nextResponder?.scrollWheel(with: event)
            return
        }

        /*
         Check the scroll direction only at the beginning of a gesture for modern scrolling devices
         Check every event for legacy scrolling devices
         */

        if event.phase == .began || (event.phase == [] && event.momentumPhase == [])
        {
            switch scrollDirection {
            case .vertical:
                currentScrollMatches = fabs(event.scrollingDeltaY) > fabs(event.scrollingDeltaX)
            case .horizontal:
                currentScrollMatches = fabs(event.scrollingDeltaX) > fabs(event.scrollingDeltaY)
            }
        }

        if currentScrollMatches {
            super.scrollWheel(with: event)
        } else {
            self.nextResponder?.scrollWheel(with: event)
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8623785

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档