8

Can we change the color of the divider? Apple documentations says, that we can override -dividerColor in subclass of NSSplitView for this, but it doesn't works for me, or my understanding isn't correct. Also I've try create color layer over divider, e.g.:

colorLayer = [CALayer layer];
NSRect dividerFrame = NSMakeRect([[self.subviews objectAtIndex:0] frame].size.width, [[self.subviews objectAtIndex:0] frame].origin.y, [self dividerThickness], self.frame.size.height);

[colorLayer setBackgroundColor:[color coreGraphicsColorWithAlfa:1]];
[colorLayer setFrame:NSRectToCGRect(dividerFrame)];

[self.layer addSublayer:colorLayer];

Not works.

Akki
  • 1,487
  • 14
  • 25

6 Answers6

10

This answer may be late but:
If you are using Interface Builder, it is possible to change the property by going to the Identity Inspector of the NSSplitView (cmd+alt+3) and adding a User Defined Runtime Attribute for dividerColor of the type Color.

Palle
  • 11,511
  • 2
  • 40
  • 61
8

Actually, simply subclassing NSSplitView and overriding -(void)dividerColor works, but works only for thin or thick divider.

I've created simple configurable split view like this:

@interface CustomSplitView : NSSplitView
@property NSColor* DividerColor
@end

@implementation CustomSplitView
- (NSColor*)dividerColor {
  return (self.DividerColor == nil) ? [super dividerColor] : self.DividerColor;
}
@end

Then in Interface Builder specify custom class for your split view to be CustomSplitView and add new user defined runtime attribute with key path = DividerColor, type = Color and select desired splitter color.

Sergio
  • 1,040
  • 13
  • 14
7

I've tried subclassing - (void)dividerColor too and I'm not sure why it doesn't work even though I know it's being called (and it's in the documentation).

One way to change the color of the divider is to subclass - (void)drawDividerInRect:(NSRect)aRect. However, for some reason, this method isn't called and I've checked all over the web for answers, but couldn't find anything, so I ended up calling it from drawRect. Here is the code for the subclassed NSSplitView:

-(void) drawRect {
    id topView = [[self subviews] objectAtIndex:0];
    NSRect topViewFrameRect = [topView frame];
    [self drawDividerInRect:NSMakeRect(topViewFrameRect.origin.x, topViewFrameRect.size.height, topViewFrameRect.size.width, [self dividerThickness] )];
}

-(void) drawDividerInRect:(NSRect)aRect {
    [[NSColor redColor] set];
    NSRectFill(aRect);
}
uff da
  • 597
  • 5
  • 16
5

Based on Palle's answer, but with the possibility to change the color dynamically in code, I'm currently using this solution (Swift 4):

splitView.setValue(NSColor.red, forKey: "dividerColor")

If your splitview control is part of a NSSplitViewController, you should use something like this:

splitViewController?.splitView.setValue(NSColor.red, forKey: "dividerColor")
Ely
  • 8,259
  • 1
  • 54
  • 67
  • As of macOS 11 this does not seem to work any longer, not sure if it's a bug or not. – cgiacomi Mar 11 '21 at 13:41
  • 2
    @cgiacomi I have just tested this on macOS 11, and it still works on my side. Make sure you call the code in windowDidLoad, after the splitviewcontroller is loaded – Ely Mar 11 '21 at 13:47
  • I ended up subclassing the NSSplitView and just overriding drawDivider(). But tnx for your reply, I had upvoted your answer and now did so with your comment as well because they really helped me out. But at least for me it seems like only subclassing works. Tnx again for your help. – cgiacomi Mar 11 '21 at 14:03
2

In Swift and on macOS 11 I was able to achieve this by simply subclassing the NSSPlitView and only override drawDivider()

import Foundation
import AppKit

class MainSplitView: NSSplitView {
    override func drawDivider(in rect: NSRect) {
        NSColor(named: "separatorLinesColor")?.setFill()
        rect.fill()
    }
}

I had previously tried some of the other way, listed in here and what used to work stopped working with macOS 11... but it seems that this works.

cgiacomi
  • 4,629
  • 6
  • 27
  • 33
0

One important point I haven't seen mentioned anywhere is that if you are overriding drawRect in a split view then you must call super -- otherwise drawDividerInRect: is never called. So, it should go something like this:

- (void)drawRect:(NSRect)dirtyRect {
    // your other custom drawing

    // call super last to draw the divider on top
    [super drawRect:dirtyRect];

}

- (void)drawDividerInRect:(NSRect)aRect {
    [[NSColor blueColor] set];
    NSRectFill(aRect);
}
isaiah
  • 435
  • 3
  • 13