mplappert
mplappert

Reputation: 1324

Hide scrollers while leaving scrolling itself enabled in NSScrollView

I'd like to hide the NSScrollers of NSScrollView. I'm aware of the methods setHasHorizontalScroller: and setHasVerticalScroller:. However, if I disable the scrollers, scrolling in that direction gets disabled as well. I'd like to only hide the scrollers while maintaining the possibility to scroll. Any thoughts on this?

Upvotes: 13

Views: 5171

Answers (6)

Vlad
Vlad

Reputation: 6732

The trick of setting alphaValue to zero has issue as invisible scroller still receives touches. Here is what we did in order to solve this (Swift 4).

class InvisibleScroller: NSScroller {

   override class var isCompatibleWithOverlayScrollers: Bool {
      return true
   }

   override class func scrollerWidth(for controlSize: NSControl.ControlSize, scrollerStyle: NSScroller.Style) -> CGFloat {
      return CGFloat.leastNormalMagnitude // Dimension of scroller is equal to `FLT_MIN`
   }

   public override init(frame frameRect: NSRect) {
      super.init(frame: frameRect)
      setupUI()
   }

   required init?(coder: NSCoder) {
      super.init(coder: coder)
      setupUI()
   }

   private func setupUI() {
      // Below assignments not really needed, but why not.
      scrollerStyle = .overlay
      alphaValue = 0
   }
}

Usage:

private class TabBarScrollView: NSScrollView {

   private func setupUI() {

      borderType = .noBorder
      backgroundColor = .clear
      drawsBackground = false

      horizontalScrollElasticity = .none
      verticalScrollElasticity = .none

      automaticallyAdjustsContentInsets = false
      horizontalScroller = InvisibleScroller()
   }
}

Upvotes: 8

Ashish
Ashish

Reputation: 3137

if collectionView.enclosingScrollView?.hasHorizontalScroller == true {
  collectionView.enclosingScrollView?.horizontalScroller?.scrollerStyle = .overlay
  collectionView.enclosingScrollView?.horizontalScroller?.alphaValue = 0.0
} else {
  print("horizontalScroller")
}

Make sure horizontal scroller is selected:

enter image description here

Upvotes: 2

Bo Yuan
Bo Yuan

Reputation: 49

This is my solution from sam's answer above:

[myNSScrollView setHasVerticalScroller:YES];
[_myNSScrollView setScrollerInsets:NSEdgeInsetsMake(0, 0, 0, -99999)];

The scroller will be hidden even during the scrolling process.

Upvotes: -1

sam
sam

Reputation: 3479

I'm looking for an answer to this as well since setting hasVerticalScroller = false disables trackpad scrolling for me. In the meantime, my horrible hack is to use the following in my NSScrollView subclass:

self.hasVerticalScroller = true
self.scrollerInsets.right = -999999

The scroller is technically visible, it is just way off the edge of the view. :(

Upvotes: 1

Mark Bao
Mark Bao

Reputation: 905

I was able to do this by doing:

[labelsScrollView setHasHorizontalScroller:YES];
[[labelsScrollView horizontalScroller] setAlphaValue:0];

Upvotes: 12

0xDE4E15B
0xDE4E15B

Reputation: 1294

Have you checked the NSScrollView Class Reference ?

[scrollView setHasVerticalScroller:NO];

this method doesn't disable scrolling.

If you still do not want to use that method you can also:

[scrollView setHorizontalScroller:nil];

Upvotes: 0

Related Questions