Disable scrolling in NSTableView

Is there an easy way to disable NSTableView scrolling.

It seems to be on [myTableView enclosingScrollView] or [[myTableView enclosingScrollView] contentView] to disable it.

+7
source share
5 answers

This works for me: subclass NSScrollView, setting and overriding via:

 - (id)initWithFrame:(NSRect)frameRect; // in case you generate the scroll view manually - (void)awakeFromNib; // in case you generate the scroll view via IB - (void)hideScrollers; // programmatically hide the scrollers, so it works all the time - (void)scrollWheel:(NSEvent *)theEvent; // disable scrolling @interface MyScrollView : NSScrollView @end #import "MyScrollView.h" @implementation MyScrollView - (id)initWithFrame:(NSRect)frameRect { self = [super initWithFrame:frameRect]; if (self) { [self hideScrollers]; } return self; } - (void)awakeFromNib { [self hideScrollers]; } - (void)hideScrollers { // Hide the scrollers. You may want to do this if you're syncing the scrolling // this NSScrollView with another one. [self setHasHorizontalScroller:NO]; [self setHasVerticalScroller:NO]; } - (void)scrollWheel:(NSEvent *)theEvent { // Do nothing: disable scrolling altogether } @end 

Hope this helps.

+14
source

Thanks to @titusmagnus for the answer, but I made one modification so as not to scroll when the "disabled" scrollView is nested in another scrollView: you cannot scroll the external scrollView while the cursor is within the internal scrollView. If you do this ...

 - (void)scrollWheel:(NSEvent *)theEvent { [self.nextResponder scrollWheel:theEvent]; // Do nothing: disable scrolling altogether } 

... then the β€œdisabled” scrollView passes the scroll event to an external scrollView, and its scroll will not get stuck inside its subzones.

+8
source

Here is the best solution in my opinion:

Swift 4

 import Cocoa @IBDesignable @objc(BCLDisablableScrollView) public class DisablableScrollView: NSScrollView { @IBInspectable @objc(enabled) public var isEnabled: Bool = true public override func scrollWheel(with event: NSEvent) { if isEnabled { super.scrollWheel(with: event) } else { nextResponder?.scrollWheel(with: event) } } } 


Just replace any NSScrollView with DisablableScrollView (or BCLDisablableScrollView if you are still using ObjC) and you're done. Just install isEnabled in code or in IB, and it will work as expected.

The main advantage it has for nested scroll views; disabling children without sending an event to the next respondent will also effectively disable parents when the cursor is over a disabled child.

Here are all the benefits of this approach, listed:

  • βœ… disables scrolling
    • βœ… does it programmatically, behaves normally by default
  • βœ… does not interrupt the scrolling of the parent view
  • Interface Developer Integration
  • βœ… Plug-in replacement for NSScrollView
  • βœ… Swift and Objective-C compatible
+5
source

There is no easy direct way (this means there is no property like UITableView scrollEnabled that you can set), but I found this answer useful in the past.

Another thing you could try (not sure about) is to subclass NSTableView and override -scrollWheel and -swipeWithEvent so that they don't do anything. Hope this helps

+2
source

Works for me:

 - (void)scrollWheel:(NSEvent *)theEvent { [super scrollWheel:theEvent]; if ([theEvent deltaY] != 0) { [[self nextResponder] scrollWheel:theEvent]; } } 
+1
source

All Articles