NSScrollView在另一个NSScrollView中

NeX*_*tep 4 cocoa nsscrollview

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

目前我scrollWheel:从内部视图将事件传递到外部视图,但它非常慢.

Jak*_*ger 6

我也有嵌套滚动视图的问题.内部滚动视图应水平滚动,外部应垂直滚动.

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

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

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

@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
Run Code Online (Sandbox Code Playgroud)

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

  • 这主要适用于10.10.我需要添加`+(BOOL)isCompatibleWithResponsiveScrolling {return YES; 因为NSScrollView检测到`-scrollWheel:`的覆盖,我认为在非响应式滚动中存在一个错误. (2认同)

use*_*889 2

这是我的 NSScrollView 子类,可以满足您的要求。由于它只是传递事件,因此不关心响应者链,因此它应该像不是子类(或至少接近)一样高效

.h 文件

#import <Cocoa/Cocoa.h>

@interface HorizontalScrollView : NSScrollView

@end
Run Code Online (Sandbox Code Playgroud)

和米

@implementation HorizontalScrollView

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

}
@end
Run Code Online (Sandbox Code Playgroud)