In my project an NSSlider controls the volume of a AVPlayer. I'd like to colorize the portion of the NSSlider left of the knob. How can this be achieved?
Asked
Active
Viewed 526 times
1
-
From what I remember this is kind of a pain, but you have to subclass nsslider and override drawRect: but you have to send the proper messages to the sliders knob cell to draw in the correct place... There may be an easier way, I will look at some examples tomorrow. – Grady Player Nov 20 '12 at 04:48
2 Answers
1
You should use NSProgressIndicator
for that.
As alternative, you can use a custom NSSliderCell and override - (BOOL)_usesCustomTrackImage
to return YES
and override - (void)drawBarInside:(NSRect)cellFrame flipped:(BOOL)flipped
to draw your custom bar. There, you can use [NSCell doubleValue] to get the current position of the slider.

Yoav
- 5,962
- 5
- 39
- 61
0
You should subclass NSSliderCell and write something like this:
@interface CustomSliderCell : NSSliderCell {
NSRect _barRect;
NSRect _currentKnobRect;
}
// You should set image for the barFill
// (or not if you want to use the default background)
// And image for the bar before the knob image
@property (strong, nonatomic) NSImage *barFillImage;
@property (strong, nonatomic) NSImage *barFillBeforeKnobImage;
// Slider also has the ages so you should set
// the different images for the left and the right one:
@property (strong, nonatomic) NSImage *barLeftAgeImage;
@property (strong, nonatomic) NSImage *barRightAgeImage;
@end
And implementation:
- (void)drawKnob:(NSRect)knobRect {
[super drawKnob:knobRect];
_currentKnobRect = knobRect;
}
-(void)drawBarInside:(NSRect)cellFrame flipped:(BOOL)flipped {
_barRect = cellFrame;
NSRect beforeKnobRect = [self createBeforeKnobRect];
NSRect afterKnobRect = [self createAfterKnobRect];
// Draw bar before the knob
NSDrawThreePartImage(beforeKnobRect, _barLeftAgeImage, _barFillBeforeKnobImage, _barFillBeforeKnobImage,
NO, NSCompositeSourceOver, 1.0, flipped);
// If you want to draw the default background
// add the following line at the at the beginning of the method:
// [super drawBarInside:cellFrame flipped:flipped];
// And comment the next line:
NSDrawThreePartImage(afterKnobRect, _barFillImage, _barFillImage, _barRightAgeImage,
NO, NSCompositeSourceOver, 1.0, flipped);
}
- (NSRect)createBeforeKnobRect {
NSRect beforeKnobRect = _barRect;
beforeKnobRect.size.width = _currentKnobRect.origin.x + _knobImage.size.width / 2;
beforeKnobRect.size.height = _barFillBeforeKnobImage.size.height;
beforeKnobRect.origin.y = beforeKnobRect.size.height / 2;
return beforeKnobRect;
}
- (NSRect)createAfterKnobRect {
NSRect afterKnobRect = _currentKnobRect;
afterKnobRect.origin.x += _knobImage.size.width / 2;
afterKnobRect.size.width = _barRect.size.width - afterKnobRect.origin.x;
afterKnobRect.size.height = _barFillImage.size.height;
afterKnobRect.origin.y = afterKnobRect.size.height / 2;
return afterKnobRect;
}
I've created LADSLider which will help you to create what you want really simple and fast.

Doshipak
- 211
- 1
- 2
- 9