8
votes

I have an NSCollectionView and I would like to hide the horizontal scroll indicators.

I've tried

        collectionView.enclosingScrollView?.verticalScroller?.isHidden = true

But it is not working.

Thank you in advance.

10
try this line of code. collectionView.enclosingScrollView?.horizontalScroller?.isHidden = trueaBilal17
Have you figured this out? I have the same problem but unchecking the "Show xyz Scroller" does not remove the scroll indicator. I think the NSCollectionViewFlowLayout might add the indicator again.retterdesapok
Unfortunately not.Jonathanff
@Jonathanff Hi, Have you figured this out?Bohdan Savych
unfortunately no :(Jonathanff

10 Answers

7
votes

hidden didn't work for me too.

The only way I found to hack this, is by changing inset:

(scrollViewCollectionView is of type NSScrollView, this example is while creating NSCollectionView programmatically)

scrollViewCollectionView.documentView?.enclosingScrollView?.scrollerInsets = NSEdgeInsets.init(top: 0, left: 0, bottom: 100, right: 0)

Please note: My NSCollectionView is horizontal, and less then 100 height, this is why this hack resolved in a hidden indicator.

2
votes
  1. Create an outlet for the ScrollView which contains the CollectionView as seen here. I've named mine @IBOutlet weak var collectionViewScrollView: NSScrollView!
  2. in viewDidAppear() function add:

    collectionViewScrollView.scrollerStyle = .legacy collectionViewScrollView.verticalScroller?.isHidden = true - for vertical scroll collectionViewScrollView.horizontalScroller?.isHidden = true - for horizontal scroll

For some reason, in my case it only works if I set the collectionViewScrollView.scrollerStyle to .legacy. Not sure why, but it works.

1
votes

Setting "Show Vertical Scroller" or "Show Horizontal Scroller" in storyboard doesn't remove the scrollers without setting constrains (height and width) of Bordered Scroll View of Collection View. After I did that and unchecked "Show Vertical Scroller" and "Show Horizontal Scroller" in Attributes Panel in storyboard they disappeared.

1
votes

I got same problem and just solve it. You can write your own custom NSScrollView and override 2 stored property: hasHorizontalScroller, horizontalScroller, and 1 function scrollWheel(with:). Here's my code:

class MyScrollView: NSScrollView {
    override var hasHorizontalScroller: Bool {
        get {
            return false
        }
        set {
            super.hasHorizontalScroller = newValue
        }
    }

    override var horizontalScroller: NSScroller? {
        get {
            return nil
        }
        set {
            super.horizontalScroller = newValue
        }
    }
    //comment it or use super for scrroling
    override func scrollWheel(with event: NSEvent) {}
}

And don't forget to set Border Scroll View class to MyScrollView in .xib or storyboard. Enjoy it!

1
votes

Override hasHorizontalScroller or horizontalScroller to false and nil will cause NSScroller not to be displayed, and NSScrollView will not respond to scroll events.

This means that you can't scroll through NSScrollView's many scrolling methods.

When hasHorizontalScroller = true, horizontalScroller != nil will cause a drawing error.

 class MyScrollView : NSScrollView {

    // !!! Don't use this !!!
    override var hasHorizontalScroller: Bool {
        get {
            // return false will cause NSScroller not to be displayed
            // and NSScrollView will not respond to scroll events,
            // this means that you can't scroll through NSScrollView's many scrolling methods.
            false
        }
        set {
            super.hasHorizontalScroller = newValue
        }
    }

    // !!! Don't use this !!!
    override var horizontalScroller: NSScroller? {
        get {
            // return nil will cause NSScroller not to be displayed,
            // but it still occupies the drawing area of the parent view.
            nil
        }
        set {
            super.horizontalScroller = newValue
        }
    }
}

wrong usage preview1

wrong usage preview2

This is the way to hide NSScroller and respond to scroll events correctly. Only useful in versions above 10.7:

class HiddenScroller: NSScroller {

    // @available(macOS 10.7, *)
    // let NSScroller tell NSScrollView that its own width is 0, so that it will not really occupy the drawing area.
    override class func scrollerWidth(for controlSize: ControlSize, scrollerStyle: Style) -> CGFloat {
        0
    }
}
0
votes

You can also achieve that via storyboard

enter image description here

0
votes

I also meet the same problem. MCMatan is right. Please adjust the position of scroller to some place invisible.

scrollView.scrollerInsets = NSEdgeInsets.init(top: 0, left: 0, bottom: -10, right: 0)
0
votes

for Swift 4 & 5 in UIKit:

for Horizontal:

collectionView.showsHorizontalScrollIndicator = false

For Vertical:

collectionView.showsVerticalScrollIndicator = false
0
votes
In my case, the horizontal and vertical scroller of the collection scroll view are only hidden if do exactly as follow:

1. In Interface Builder.
1.a. Select Scroll View —> Attributes Inspector:
    + Uncheck Show Horizontal Scroller.
    + Uncheck Show Vertical Scroller.
    + Uncheck Automactically Hide Scroller.
1.b. Select Size Inspector:
    + Uncheck Automatically Adjust.
1.c. Select Clip View —> Size Inspector:
    + Uncheck Automatically Adjust.
2. In code do exactly as follow:

[self.scrollView setBackgroundColor:[NSColor clearColor]];
[self.scrollView setBorderType:NSNoBorder];
[self.scrollView setHasVerticalScroller:NO];
[self.scrollView setHasHorizontalScroller:NO];
[self.scrollView setAutomaticallyAdjustsContentInsets:NO];
[self.scrollView setContentInsets:NSEdgeInsetsMake(0.0, 0.0, -NSHeight([self.scrollView horizontalScroller].frame), -NSWidth([self.scrollView verticalScroller].frame))];
[self.scrollView setScrollerInsets:NSEdgeInsetsMake(0.0, 0.0, -NSHeight([self.scrollView horizontalScroller].frame), -NSWidth([self.scrollView verticalScroller].frame))];
[self.scrollView setScrollEnable:NO];

NSClipView *clipView = (NSClipView *)[self.scrollView documentView];

if ([clipView isKindOfClass:[NSClipView class]])
{
    [clipView setAutomaticallyAdjustsContentInsets:NO];
    [clipView setContentInsets:NSEdgeInsetsZero];
}

Then the NSCollectionView will fit to the Clip View as same width and height without the horizontal and vertical scrollers.
0
votes

If someone still needs it, this one trick should work

collectionView.enclosingScrollView?.horizontalScroller?.alphaValue = 0.0