Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable scrolling in NSTableView

Is there a simple way to disable scrolling of an NSTableView.

It seems there isn't any property on [myTableView enclosingScrollView] or [[myTableView enclosingScrollView] contentView] to disable it.

like image 407
erkanyildiz Avatar asked Sep 27 '12 16:09

erkanyildiz


2 Answers

Here's the best solution in my opinion:

Swift 5

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)
        }
    }
}


Simply replace any NSScrollView with DisablableScrollView (or BCLDisablableScrollView if you still use ObjC) and you're done. Simply set isEnabled in code or in IB and it will work as expected.

The main advantage that this has is for nested scroll views; disabling children without sending the event to the next responder will also effectively disable parents while the cursor is over the disabled child.

Here are all advantages of this approach listed out:

  • ✅ Disables scrolling
    • ✅ Does so programmatically, behaving normally by default
  • ✅ Does not interrupt scrolling a parent view
  • ✅ Interface Builder integration
  • ✅ Drop-in replacement for NSScrollView
  • ✅ Swift and Objective-C Compatible
like image 112
Ky. Avatar answered Sep 23 '22 18:09

Ky.


This works for me: subclass NSScrollView, setup and override 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

I hope this helps.

like image 22
titusmagnus Avatar answered Sep 22 '22 18:09

titusmagnus