indragie
indragie

Reputation: 18122

Overlay NSScroller over content

Is there any way to overlay the NSScroller over the content of the scroll view (like in iOS)? I've already tried several approaches:

a) setting the frame of the scroll view content view (NSClipView) to extend into the bounds of the scroller

b) adding an NSScroller object as a subview of the scroll view (positioned where I want)

c) creating an entirely custom scroller view and placing it as a subview (this worked, but that would mean that I need to rewrite all the functionality of NSScroller)

Sparrow seems to successfully do this, and it seems to do it through a regular NSScroller subclass (seeing as it responds to the scroll settings set in System Preferences >> Appearance). It's not really drawing the scroller that's the issue, its just making it overlay the content.

Any advice is appreciated :-)

Upvotes: 7

Views: 4002

Answers (4)

Ely
Ely

Reputation: 9141

You can change the scrollerStyle over the NSScrollerView control to .overlay to get the desired overlay effect.

This may overrule the system wide setting in System Settings for scroll bar visibility. To 'survive' scroll bar setting changes while your app is running, you must observe the NSScroller.preferredScrollerStyleDidChangeNotification and re-apply the overlay effect.

Upvotes: 0

tim
tim

Reputation: 1682

I've recently released RFOverlayScrollView which should solve your problem:

Source: https://github.com/rheinfabrik/RFOverlayScrollView

Blog Post: http://blog.rheinfabrik.de/blog/2013/01/01/introducing-rfoverlayscrollview/

Upvotes: 0

Benjamin
Benjamin

Reputation: 2807

Here is my solution : Create a MyScroller class that extends NSScroller

In the MyScroller.m :

#import "MyScroller.h"


@implementation MyScroller

+(CGFloat) scrollerWidth{
    return 10;
}

+(CGFloat) scrollerWidthForControlSize:(NSControlSize)controlSize{
    return 10;
}

- (void) drawBackground:(NSRect) rect{
    NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:0 yRadius:0];
    [[NSColor whiteColor] set];
    [path fill];
}

- (void)drawKnob{
    [self drawBackground:[self rectForPart:0]];
    [self drawBackground:[self rectForPart:1]];
    [self drawBackground:[self rectForPart:2]];
    [self drawBackground:[self rectForPart:4]];
    [self drawBackground:[self rectForPart:5]];
    [self drawBackground:[self rectForPart:6]];


    NSRect knobRect = [self rectForPart:NSScrollerKnob];
    NSRect newRect = NSMakeRect((knobRect.size.width - [MyScroller scrollerWidth]) / 2, knobRect.origin.y, [MyScroller scrollerWidth], knobRect.size.height);
    NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:newRect xRadius:5 yRadius:5];
    [[NSColor grayColor] set];
    [path fill];
}
@end

Then just set the custom class for the Scroller in Interface Builder.

Upvotes: 4

Hoà
Hoà

Reputation: 86

Here's where you can set the custom class of your scrollbars.

After that, by overriding the -tile method of NSScrollView, you'll get them placed properly.

Upvotes: 7

Related Questions