Reputation: 11760
I am trying to create a round button which is only clickable in its boundaries.
What I have done
// imported QuartzCore
#import <QuartzCore/QuartzCore.h>
//created an IBOutlet for the button
IBOutlet NSButton* btn;
//defined the button height width (same)
#define ROUND_BUTTON_WIDTH_HEIGHT 150
//set corner radius
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
btn.frame = CGRectMake(0, 0, ROUND_BUTTON_WIDTH_HEIGHT, ROUND_BUTTON_WIDTH_HEIGHT);
btn.layer.cornerRadius = ROUND_BUTTON_WIDTH_HEIGHT/2.0f;
}
//set view layer to YES
Problem
I have also tried to subclass NSButton
and assign the class to the button but results are the same.
#import "roundBtn.h"
#import <QuartzCore/QuartzCore.h>
@implementation roundBtn
#define ROUND_BUTTON_WIDTH_HEIGHT 142
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
// Drawing code here.
self.frame = CGRectMake(0, 0, ROUND_BUTTON_WIDTH_HEIGHT, ROUND_BUTTON_WIDTH_HEIGHT);
self.layer.cornerRadius = ROUND_BUTTON_WIDTH_HEIGHT/2.0f;
}
@end
Upvotes: 0
Views: 346
Reputation: 7049
You can either reimplement the button behavior using a custom NSView and then it will respect the mouseDown events of a masksToBounds layer. NSButton doesn't work this way so the only way to tell your subclassed button that it won't be hit outside of the circle is to override the -hitTest:
method to detect hits within the circle:
- (NSView *)hitTest:(NSPoint)aPoint {
NSPoint p = [self convertPoint:aPoint fromView:self.superview];
CGFloat midX = NSMidX(self.bounds);
CGFloat midY = NSMidY(self.bounds);
if (sqrt(pow(p.x-midX, 2) + pow(p.y-midY, 2)) < self.bounds.size.width/2.0) {
return self;
}
return nil;
}
In overriding this, you are telling the button that it will only register a hit if it is within the circle (using a little trigonometry). Returning self indicates the button was hit, returning nil indicates it was not hit.
Upvotes: 1