NSScrollView внутри другого NSScrollView - PullRequest
4 голосов
/ 24 декабря 2011

У меня есть NSScrollview, вложенное в другое NSScrollview.Как сделать так, чтобы внутренний вид обрабатывал только горизонтальную прокрутку?Вертикальная прокрутка должна перемещать внешний вид.

В настоящее время я передаю событие scrollWheel: внешнему виду из внутреннего вида, но оно очень медленное.

Ответы [ 3 ]

6 голосов
/ 29 ноября 2012

У меня также была проблема вложенных представлений прокрутки.Внутреннее представление прокрутки должно прокручиваться по горизонтали, а внешнее прокручивание по вертикали.

При обработке событий прокрутки с помощью волшебной мыши / трекпада важно выбрать только одно из представлений прокрутки для каждого жеста, в противном случае вы увидитестранный рывок, когда ваши пальцы не двигаются идеально ровно.Вы также должны убедиться, что касание трекпада двумя пальцами показывает оба скроллера.

При обработке устаревших событий прокрутки от могучей мыши или мыши со старомодными колесами прокрутки необходимо выбрать правильный вид прокрутки для каждого события, потому чтоотсутствует информация о фазе жеста в событиях.

Это мой подкласс для представления внутренней прокрутки, протестированный только в 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

Моя реализация не всегда правильно передает события отмены жеста, но по крайней мере в 10.8 это не вызывает проблем.

1 голос
/ 19 июля 2012

Это мой подкласс NSScrollView, который делает то, что вы просите.Так как он просто передает события, он не заботится о цепочке респондента, он должен быть таким же быстродействующим, как если бы он не был подклассом (или, по крайней мере, близким)

h file

#import <Cocoa/Cocoa.h>

@interface HorizontalScrollView : NSScrollView

@end

и м

@implementation HorizontalScrollView

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

}
@end
0 голосов
/ 19 декабря 2018

Swift 4.

Ответ - перевод превосходного ответа Якоба выше, с добавлением флага направления.

Как уже упоминалось в комментариях к его ответу, могут быть тонкие осложненияесли это не сделано правильно.Когда я просто переадресовывал все вызовы scrollWheel () следующему респонденту, я видел проблемы, связанные с тем, что NSTrackingAreas не обновляется корректно, а подсказки и стили курсора над представлениями NSTextView не выравниваются.

...