1

要在 Dock 中为您的应用程序添加徽章很容易,您只需调用[NSDockTile setBadgeLabel]. 但我想给一个通用的 NSView 添加一个徽章。有没有办法做到这一点?或者如果做不到这一点,您如何绘制一个以使其看起来与系统 UI 的其余部分一致?

4

2 回答 2

4

没有内置方法可以绘制徽章,NSView因此您应该自己绘制。这是我绘制徽章的代码:

- (void)drawBadgeImageWithText:(NSString*)text atPoint:(NSPoint)point
{
    NSSize badgeSize = [self badgeSizeForString:text];
    NSRect badgeRect = NSMakeRect(point.x - badgeSize.width, point.y - badgeSize.height, badgeSize.width, badgeSize.height);

    [NSGraphicsContext saveGraphicsState];

    // Set a shadow
    NSShadow* shadow = [[NSShadow alloc] init];
    shadow.shadowColor = [[NSColor blackColor] colorWithAlphaComponent:0.4];
    shadow.shadowBlurRadius = 1;
    shadow.shadowOffset = NSMakeSize(0, -1);
    [shadow set];

    // Draw white border
    NSBezierPath* path = [NSBezierPath bezierPathWithRoundedRect:badgeRect xRadius:badgeSize.height / 2.0 yRadius:badgeSize.height / 2.0];
    [[NSColor whiteColor] setFill];
    [path fill];

    [NSGraphicsContext restoreGraphicsState];

    // Fill the background with red gradient 
    badgeRect = NSInflateRect(badgeRect, -1.5, -1.5);
    path = [NSBezierPath bezierPathWithRoundedRect:badgeRect xRadius:badgeSize.height / 2.0 yRadius:badgeSize.height / 2.0];
    [[NSColor colorWithCalibratedRed:192.0 / 255.0 green:0.0 blue:0.0 alpha:1.0] setFill];
    [path fill];

    NSGradient* gradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedRed:241.0 / 255.0 green:113.0 / 255.0 blue:115.0 / 255.0 alpha:1.0]
                                                         endingColor:[NSColor colorWithCalibratedRed:192.0 / 255.0 green:0.0 blue:0.0 alpha:1.0]];
    [gradient drawInBezierPath:path angle:-90.0];

    // Draw the text
    NSMutableParagraphStyle* paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    [paragraphStyle setAlignment:NSCenterTextAlignment];

    NSDictionary* textAttributes = @{NSForegroundColorAttributeName:[NSColor whiteColor], NSParagraphStyleAttributeName:paragraphStyle};

    [text drawInRect:badgeRect withAttributes:textAttributes];
}

- (NSSize)badgeSizeForString:(NSString*)string
{
    NSDictionary* attributes = [NSDictionary dictionaryWithObject:[NSFont systemFontOfSize:13] forKey: NSFontAttributeName];
    NSSize size = [string sizeWithAttributes:attributes];

    // Paddings
    size.height += 2.0;
    size.width += 12.0;

    return size;
}
于 2013-11-07T08:24:06.270 回答
0

我将Dmitry的答案移植到 Swift 3;这是为了以防它为其他人节省一些时间。

func badgeSizeForString(string:String) -> NSSize {
    var size = string.size(withAttributes: [NSFontAttributeName: NSFont.systemFont(ofSize: 13.0)])

    // Paddings
    size.height += 2.0
    size.width += 12.0

    return size
}

func drawBadgeImageWithText(text:NSString, atPoint point: NSPoint) -> Void {
    let badgeSize = badgeSizeForString(string: text as String)
    var badgeRect = NSMakeRect(point.x - badgeSize.width,
                               point.y - badgeSize.height,
                               badgeSize.width,
                               badgeSize.height)

    NSGraphicsContext.saveGraphicsState()

    // Set a shadow
    let shadow = NSShadow()
    shadow.shadowColor = NSColor.black.withAlphaComponent(0.4)
    shadow.shadowBlurRadius = 1;
    shadow.shadowOffset = NSMakeSize(0, -1);
    shadow.set()

    // Draw white border
    var path = NSBezierPath(roundedRect: badgeRect,
                            xRadius:badgeSize.height / 2.0,
                            yRadius:badgeSize.height / 2.0)
    NSColor.white.setFill()
    path.fill()

    NSGraphicsContext.restoreGraphicsState()

    // Fill the background with red gradient
    badgeRect = NSInsetRect(badgeRect, -1.5, -1.5)
    path = NSBezierPath(roundedRect: badgeRect,
                        xRadius:badgeSize.height / 2.0,
                        yRadius:badgeSize.height / 2.0)
    NSColor(calibratedRed:192.0 / 255.0,
            green:0.0,
            blue:0.0,
            alpha:1.0).setFill()
    path.fill()

    let gradient = NSGradient(starting: NSColor(calibratedRed:241.0 / 255.0,
                                                green:113.0 / 255.0,
                                                blue:115.0 / 255.0,
                                                alpha:1.0),
                              ending: NSColor(calibratedRed:192.0 / 255.0,
                                              green:0.0,
                                              blue:0.0,
                                              alpha:1.0))
    gradient?.draw(in: path, angle:-90.0)

    // Draw the text
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = .center

    let textAttributes = [ NSForegroundColorAttributeName: NSColor.white, NSParagraphStyleAttributeName: paragraphStyle ]
    text.draw(in: badgeRect, withAttributes: textAttributes)
}
于 2017-08-11T01:06:12.270 回答