Hide scrollers while leaving scrolling itself enabled in NSScrollView
Asked Answered
F

6

13

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?

Fibula answered 20/2, 2012 at 16:49 Comment(0)
C
12

I was able to do this by doing:

[labelsScrollView setHasHorizontalScroller:YES];
[[labelsScrollView horizontalScroller] setAlphaValue:0];
Calculus answered 10/7, 2013 at 14:18 Comment(2)
Thanks, this is still working on macOS 10.13.4 with Swift. I did need to set the .scrollerStyle to .overlay for it to work though. For some reason with .legacy the "background" of the scrollbar is still drawn.Edeline
Scroller is not visible, but still can receive touches :0Semolina
S
8

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()
   }
}
Semolina answered 7/6, 2018 at 7:28 Comment(0)
S
2
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

Stationmaster answered 2/8, 2018 at 10:21 Comment(0)
P
1

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. :(

Punic answered 26/3, 2016 at 17:18 Comment(0)
H
0

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];
Heliogravure answered 20/2, 2012 at 17:37 Comment(2)
my English ( Thank you, rokjarc.Heliogravure
Doesn't work. Setting either of these actions results in a scroll view that no longer responds to scroll events for that direction.Blackmail
S
-1

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.

Seigniory answered 31/8, 2017 at 2:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.