Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSImageView rounded corners + stroke

I have subclasses NSImageView and i want to draw a border around with rounded corners. It works but i need to clip off the image corners as well.

Please see my screenshot:

enter image description here

I have created this code to draw the border/corners.

- (void)drawRect:(NSRect)dirtyRect
{
    [super drawRect:dirtyRect];

    NSColor *strokeColor;
    if(self.isSelected)
        strokeColor = [NSColor colorFromHexRGB:@"f9eca2"];
    else
        strokeColor = [NSColor colorFromHexRGB:@"000000"];

    [strokeColor set];    
    [[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(dirtyRect, 1, 1) xRadius:5 yRadius:5] stroke];
}

What should i do to make the image clip ?

EDIT:

Well i fixed it, but i feel its an ugly way to do it. Anything smarter?

NEW CODE:

- (void)drawRect:(NSRect)dirtyRect
{
    NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(dirtyRect, 2, 2) xRadius:5 yRadius:5];

    [path setLineWidth:4.0];
    [path addClip];

    [self.image drawAtPoint: NSZeroPoint
                 fromRect:dirtyRect
                 operation:NSCompositeSourceOver
                 fraction: 1.0];

    [super drawRect:dirtyRect];

    NSColor *strokeColor;
    if(self.isSelected)
    {
        strokeColor = [NSColor colorFromHexRGB:@"f9eca2"];
    }
    else
        strokeColor = [NSColor colorFromHexRGB:@"000000"];

    [strokeColor set];    
    [NSBezierPath setDefaultLineWidth:4.0];
    [[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(dirtyRect, 2, 2) xRadius:5 yRadius:5] stroke];
}
like image 776
Rasmus Styrk Avatar asked Mar 04 '12 10:03

Rasmus Styrk


2 Answers

Set the corner radius of your NSImageViews layer also to 5 px and set its maskToBounds property to YES.

like image 179
yinkou Avatar answered Sep 19 '22 08:09

yinkou


updated answer for XCode 8.3 and Swift 3.1

import Cocoa

class SomeViewController: NSViewController {
  @IBOutlet weak var artwork: NSImageView!

  override func viewDidLoad() {
    super.viewDidLoad()
    artwork.wantsLayer = true // Use a layer as backing store for this view
    artwork.canDrawSubviewsIntoLayer = true // Important, flatten all subviews into layer
    artwork.layer?.cornerRadius = 4.0
    artwork.layer?.masksToBounds = true // Mask layer
  }
}
like image 21
gf3 Avatar answered Sep 19 '22 08:09

gf3