Reputation: 14068
I have an NSTableView
and within each table row there is an NSTextView
. I have disabled scrolling on the NSTextView
in my storyboard. I can scroll my NSTableView
just fine, but when my mouse cursor is over the top of the NSTextView
, the scrolling stops. I assume this is because the NSTextView
is intercepting the scroll behavior.
The arrow points to the NSTextView
:
Keep in mind that the NSTextView
is in a subclassed NSTableViewCell
.
class AnnouncementsVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
@IBOutlet weak var tableView: NSTableView!
override func viewDidLoad() {
//...
}
func numberOfRows(in tableView: NSTableView) -> Int {
//...
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
//...
}
}
class AnnouncementTableCell: NSTableCellView{
@IBOutlet weak var message: NSTextView!
}
How do I make the NSTextView
pass its scroll events up to its parent NSTableView
? My guess is I will need scrollWheel(with event: NSEvent)
but I'm unsure where it goes since I have two different classes at play here.
Upvotes: 1
Views: 460
Reputation: 14068
Here's a Swift (4.2) version that works great:
class MyScrollClass: NSScrollView{
override func scrollWheel(with event: NSEvent) {
self.nextResponder?.scrollWheel(with: event)
}
}
Just add that sub-class your NSScrollView
and it should work.
Upvotes: 2
Reputation: 391
One way to achieve this would be to subclass NSScrollView
and implement scrollWheel:
to conditionally (1) either consume scroll-events in your subclass-instance as needed, or (2) forward them to an enclosing scrollview, based on your instances' current scrollposition.
Here's a rather rudimentary implementation (Obj-C) that i've used in the past:
- (void)scrollWheel:(NSEvent *)e {
if(self.enclosingScrollView) {
NSSize
contSize = self.contentSize,
docSize = [self.documentView bounds].size,
scrollSize = NSMakeSize(MAX(docSize.width - contSize.width, 0.0f),
MAX(docSize.height - contSize.height,0.0f) );
NSPoint
scrollPos = self.documentVisibleRect.origin,
normPos = NSMakePoint(scrollSize.width ? scrollPos.x/scrollSize.width : 0.0,
scrollSize.height ? scrollPos.y/scrollSize.height : 0.0 );
if( ((NSView*)self.documentView).isFlipped ) normPos.y = 1.0 - normPos.y;
if( ( e.scrollingDeltaX>0.0f && normPos.x>0.0f)
|| ( e.scrollingDeltaX<0.0f && normPos.x<1.0f)
|| ( e.scrollingDeltaY<0.0f && normPos.y>0.0f)
|| ( e.scrollingDeltaY>0.0f && normPos.y<1.0f) ) {
[super scrollWheel:e];
}
else
[self.nextResponder scrollWheel:e];
}
else
// Don't bother when not nested inside another NSScrollView
[super scrollWheel:e];
}
It still leaves much to be desired, like handling the deltaX and deltaY components independantly, but perhaps it's sufficient for your case.
Upvotes: 1