我有一个嵌套在另一个NSScrollview中的NSScrollview。如何使内部视图仅处理水平滚动?垂直滚动应移动外部视图。
目前,我从内部视图将scrollWheel:事件传递给外部视图,但速度非常慢。
发布于 2012-11-29 22:27:47
我还遇到了嵌套滚动视图的问题。内部滚动视图应水平滚动,外部滚动视图应垂直滚动。
当处理来自魔术鼠标/触控板的滚动事件时,为每个手势只选择一个滚动视图是很重要的,否则当你的手指不能完全伸直时,你会看到奇怪的抖动。您还应确保用两个手指轻敲触控板会同时显示两个滚动条。
在处理来自强大的鼠标或使用老式滚轮的鼠标的传统滚动事件时,您必须为每个事件选择正确的滚动视图,因为事件中没有手势阶段信息。
这是我的内部滚动视图的子类,仅在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中这不会造成问题。
发布于 2012-07-19 22:10:17
这是我的NSScrollView子类,它可以完成您所要求的任务。由于它只是将事件传递到响应器链上,而不关心这些事件,因此它的性能应该与它不是子类一样好(或者至少是close)
H文件
#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发布于 2018-12-19 17:35:36
Swift 4.
答案是上面Jakob的优秀答案的翻译,增加了一个方向标志。
正如在他回答的评论中提到的,如果这项工作做得不好,可能会出现微妙的复杂情况。当简单地将所有scrollWheel()调用转发给下一个响应器时,我看到了NSTrackingAreas没有正确更新以及NSTextView视图上的工具提示和光标样式未对齐的问题。
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)
}
}
}https://stackoverflow.com/questions/8623785
复制相似问题