Subclass NSProgressIndicator

元气小坏坏 提交于 2019-12-05 08:35:34

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 makeBackingLayer if 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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!