【问题标题】:How do I draw a top-right rounded corner on a NSButton?如何在 NSButton 上绘制右上角的圆角?
【发布时间】:2017-03-26 00:32:51
【问题描述】:

有几种方法可以在 Cocoa 中绘制四个圆角,使用 CALayer 或 NSBezierPath。但是如何在 NSButton 上绘制一个圆角?

按钮的当前结构是:

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

我想要做的是一个半径为 10 的圆形右上角。我该怎么做?

【问题讨论】:

  • 如果您发布了解决方案,为什么不将其发布为答案?

标签: cocoa nsbutton nsbezierpath


【解决方案1】:

解决方案:

覆盖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];

【讨论】:

    【解决方案2】:

    您需要使用 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)];
    

    以此类推...直到您创建一个封闭的按钮区域并获得精确的形状。

    【讨论】:

      【解决方案3】:

      基于 Christoffer Christoffer's approach,我创建了一个更通用的解决方案,您可以在其中选择要圆角的角。它在 Swift 3 中,也适用于 macOS 和 iOS/tvOS。

      您可以在此处找到 Swift Playground:https://github.com/janheiermann/BezierPath-Corners

      【讨论】:

      • 试图在mac项目上使用此代码,但不幸的是它不起作用!!!,轮数不正确,即BezierPath.init(rect:rect,roundedCorners:[.topLeft, .bottomRight],cornerRadius:8.0) 看起来完全不像预期的那样。
      • 这个项目用错了控制点,所以边角不是圆的。
      • 项目使用curve(to:...)而不是appendArc(withCenter:...)。这就是为什么它不是你所期望的。
      最近更新 更多