子类NSProgressIndicator

时间:2013-08-27 12:01:19

标签: macos cocoa subclass nsprogressindicator

我喜欢子类化NSProgressIndicator。我已经使用了这段代码,并在Interface Builder中设置了Subclass:

- (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);

当应用程序启动时,它看起来像这样: App start

但是在复制过程中,旧栏出现了。 During copying

怎么了?

2 个答案:

答案 0 :(得分:2)

似乎进度条的进度未在drawRect:中绘制,因此仅覆盖drawRect:是不够的。但是,如果您支持进度条图层,则负责执行所有绘图。

来自documentation

  

视图类会自动为您创建一个背景层(使用   makeBackingLayer如果被覆盖,则必须使用视图类   绘图机制。

检查IB中的“核心动画层”或将其添加到您的子类:

- (void)awakeFromNib {
    [super awakeFromNib];
    [self setWantsLayer:YES];
}

答案 1 :(得分:1)

我遵循了上述建议(谢谢!),但不幸的是发现当NSProgressIndicator调整大小时,它消失了,但只在第一次观看时(它在抽屉里面)。

我没有尝试理解发生了什么,而是意识到你实际上并不需要旧控件,因为我所做的非常简单(一种改变颜色的强度指示器)。只需创建NSView的子类。

所以就是这样:

@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