【问题标题】:Make NSLevelIndicator draw rounded edges使 NSLevelIndicator 绘制圆角边缘
【发布时间】:2013-12-20 22:36:18
【问题描述】:

我想为我的NSLevelIndicator 创建一个自定义类,它只是将边缘四舍五入。 (即像圆角矩形按钮) 我创建了一个自定义类,我知道我必须在

-(void)drawRect:(NSRect)dirtyRect;

方法,但我完全不知道如何实现这一点,我希望有人对此有想法。

【问题讨论】:

  • “……我知道我必须在 [drawRect:] 方法中实现它……”这里有一个问题:NSLevelIndicator 是一个控件,而不是常规视图,因此您必须至少部分工作在细胞水平。好消息是,你可能根本不需要继承 NSLevelIndicator ;坏消息是,您必须改为子类 NSLevelIndicatorCell(如果不是另外)。

标签: objective-c cocoa nslevelindicator


【解决方案1】:

@interface DILevelIndicatorCell : NSLevelIndicatorCell

@property ( readwrite, assign ) BOOL drawBezel;

@property ( readwrite, assign ) BOOL verticalCenter;

@end

- ( void )drawWithFrame:( NSRect ) rcCellFrame inView:( NSView* ) pControlView
{

    NSRect rcInterior = rcCellFrame;

    if( _drawBezel )
    {
        [ self _drawBezelWithFrame:rcCellFrame ];

        rcInterior = NSInsetRect( rcCellFrame, 3, 3 );
    }

    if( _verticalCenter )
    {
        CGFloat i = ( NSHeight( rcInterior ) - [ self cellSize ].height ) / 2;
        rcInterior.origin.y    += i;
        rcInterior.size.height -= i;
    }    

    [ super drawWithFrame:rcInterior inView:pControlView ];
}

- ( void )_drawBezelWithFrame:( NSRect ) dirtyRect
{

    CGFloat fRoundedRadius = 10.0f;

    NSGraphicsContext* ctx = [ NSGraphicsContext currentContext ];
    [ ctx saveGraphicsState ];
    {
        NSBezierPath* pPath    = [ NSBezierPath bezierPathWithRoundedRect:dirtyRect
                                                                  xRadius:fRoundedRadius
                                                                  yRadius:fRoundedRadius ];
        [ pPath setClip ];

        [ [ NSColor colorWithCalibratedRed:0.9 green:0.9 blue:0.95 alpha:1.0 ] setFill ];
        NSRectFillUsingOperation ( dirtyRect, NSCompositeSourceOver );

         [ [ NSColor colorWithCalibratedRed:0.7 green:0.7 blue:0.85 alpha:1.0 ] setFill ];
        [ pPath setLineWidth:1 ];
        [ pPath stroke ];
    }
    [ ctx restoreGraphicsState ];
}

【讨论】:

  • 谢谢,但不是我想要的那种风格。似乎只在 LevelIndicator 周围画了一条线。我正在尝试更改绿色级别指示器
【解决方案2】:

子类NSLevelIndicatorCell 并覆盖drawWithFrame:inView:

#import "CustomLevelIndicatorCell.h"

@implementation CustomLevelIndicatorCell

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {

    double level = (self.floatValue - self.minValue)/(self.maxValue- self.minValue);
    if (level > 1.0){level = 1.0;}
    NSLog(@"Level: %a", level);

    NSColor *fillColor;
    if(self.value < self.criticalValue)
        fillColor = [NSColor redColor];
    else if(self.value < self.warningValue)
        fillColor = [NSColor yellowColor];
    else
        fillColor = [NSColor greenColor];


    NSRect levelRect = NSInsetRect(cellFrame, 2, 1);
    levelRect.size.width = levelRect.size.width * level;
    NSBezierPath * levelPath = [NSBezierPath bezierPathWithRoundedRect:levelRect xRadius:3 yRadius:3];
    [fillColor setFill];
    [levelPath fill];
    NSBezierPath * indicatorPath = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(cellFrame, 2, 1) xRadius:3 yRadius:3];
    [indicatorPath setLineWidth:1];
    [[NSColor grayColor] setStroke];
    [indicatorPath stroke];

}

@end

然后您可以将NSLevelIndicator 的单元格设置为CustomLevelIndicatorCell,无论是在InterfaceBuilder 中还是在setCell: 的代码中

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 2018-07-18
    • 2013-06-24
    • 1970-01-01
    相关资源
    最近更新 更多