i like to subclass a NSProgressIndicator. I've used this code and i set the Subclass in the Interface Builder:
- (void)drawRect:(NSRect)dirtyRect {
NSRect rect = NSInsetRect([self bounds], 1.0, 1.0);
CGFloat radius = rect.size.height / 2;
NSBezierPath *bz = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:radius yRadius:radius];
[bz setLineWidth:2.0];
[[NSColor blackColor] set];
[bz stroke];
rect = NSInsetRect(rect, 2.0, 2.0);
radius = rect.size.height / 2;
bz = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:radius yRadius:radius];
[bz setLineWidth:1.0];
[bz addClip];
rect.size.width = floor(rect.size.width * ([self doubleValue] / [self maxValue]));
NSRectFill(rect);
When the app starts its looks like this:
But during the copy progress the old bar shows up.
Whats wrong?
It seems that the progress bar's progress is not drawn in drawRect:, so just overriding drawRect: is not enough. However, if you make the progress bar layer backed, you are responsible for doing all the drawing.
From the documentation:
The view class automatically creates a backing layer for you (using
makeBackingLayerif overridden), and you must use the view class’s drawing mechanisms.
Check the "Core Animation Layer" in IB or add this to your sub class:
- (void)awakeFromNib {
[super awakeFromNib];
[self setWantsLayer:YES];
}
I followed the above advice (thanks!), but unfortunately discovered that when the NSProgressIndicator was resized, it disappeared, but only on the first viewing (it was inside a drawer).
Rather than try and understand what was happening, I realised you don't actually need the old control, as what I was doing is very simple (a strength indicator that changes color). Just create a subclass of NSView.
So this is it:
@interface SSStrengthIndicator : NSView
/// Set the indicator based upon a score from 0..4
@property (nonatomic) double strengthScore;
@end
@implementation SSStrengthIndicator
- (void)setStrengthScore:(double)strength
{
if (_strengthScore != strength) {
_strengthScore = strength;
[self setNeedsDisplay:YES];
}
}
- (void)drawRect:(NSRect)dirtyRect
{
NSRect rect = NSInsetRect([self bounds], 1.0, 2.0);
double val = (_strengthScore + 1) * 20;
if (val <= 40)
[[NSColor redColor] set];
else if (val <= 60)
[[NSColor yellowColor] set];
else
[[NSColor greenColor] set];
rect.size.width = floor(rect.size.width * (val / 100.0));
[NSBezierPath fillRect:rect];
}
@end
来源:https://stackoverflow.com/questions/18464814/subclass-nsprogressindicator