Как нарисовать закругленный верхний правый угол на NSButton?

Существует несколько способов рисования закругленных углов в Cocoa, используя CALayer или NSBezierPath. Но как я могу нарисовать один закругленный угол на NSButton?

Текущая структура кнопки:

NSButton *button = [[NSButton alloc] initWithFrame:NSMakeRect(0, 0, 50, 20)];
[button setTitle:@"My button"];
[button.cell setBackgroundColor:[NSColor grayColor]];

Что я хочу сделать, так это закруглить верхний правый угол с радиусом 10. Как мне это сделать?


person Christoffer    schedule 25.02.2013    source источник
comment
Если вы разместили решение, почему бы не опубликовать его как ответ?   -  person Anoop Vaidya    schedule 25.02.2013


Ответы (3)


РЕШЕНИЕ:

Переопределить drawRect:

CGFloat cornerRadius = 10;

NSBezierPath *path = [NSBezierPath bezierPath];

// Start drawing from upper left corner
[path moveToPoint:NSMakePoint(NSMinX(self.bounds), NSMinY(self.bounds))];

// Draw top border and a top-right rounded corner
NSPoint topRightCorner = NSMakePoint(NSMaxX(self.bounds), NSMinY(self.bounds));
[path lineToPoint:NSMakePoint(NSMaxX(self.bounds) - cornerRadius, NSMinY(self.bounds))];
[path curveToPoint:NSMakePoint(NSMaxX(self.bounds), NSMinY(self.bounds) + cornerRadius)
     controlPoint1:topRightCorner
     controlPoint2:topRightCorner];

// Draw right border, bottom border and left border
[path lineToPoint:NSMakePoint(NSMaxX(self.bounds), NSMaxY(self.bounds))];
[path lineToPoint:NSMakePoint(NSMinX(self.bounds), NSMaxY(self.bounds))];
[path lineToPoint:NSMakePoint(NSMinX(self.bounds), NSMinY(self.bounds))];

// Fill path
[[NSColor whiteColor] setFill];
[path fill];
person Christoffer    schedule 26.02.2013

Вам нужно использовать NSBezierPath и нарисовать пользовательскую кнопку в соответствии с вашими требованиями.

Вам нужно работать примерно так:

NSBezierPath *path = [NSBezierPath bezierPath];
[path setLineWidth:1];
[path moveToPoint:NSMakePoint(0, 0)];

[path curveToPoint:NSMakePoint(width * 0.1, height)
     controlPoint1:NSMakePoint(width * 0.05, height)
     controlPoint2:NSMakePoint(width * 0.03, height * 0.05)];

И так далее... Пока вы не сделаете закрытую область кнопки и не получите точную форму.

person Anoop Vaidya    schedule 25.02.2013

Основываясь на подходе Кристофера, я создал более общее решение, в котором вы можете выбрать, какой угол вы хотите скруглить. Это в Swift 3, а также работает как на macOS, так и на iOS/tvOS.

Вы можете найти Swift Playground здесь: https://github.com/janheiermann/BezierPath-Corners

person JanApotheker    schedule 25.03.2017
comment
Пытался использовать этот код в проекте Mac, но, к сожалению, он не работает !!!, закругления неправильные, т.е. BezierPath.init(rect: rect, roundedCorners: [.topLeft, .bottomRight], angleRadius: 8.0) выглядит совсем не так, как задумано. - person Klajd Deda; 09.04.2018
comment
В этом проекте неправильно используются контрольные точки, поэтому углы не круглые. - person Erik Aigner; 01.09.2020
comment
В проекте используется кривая (to:...), а не appendArc (withCenter:...). Вот почему это не то, что вы ожидаете. - person danwood; 08.04.2021