IOS - 绘制圆角正方形

4
我将尝试创建一个带圆角的200像素正方形,用作IOS烤面包机式显示。

截至目前,我有以下代码 -

- (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.1].CGColor);
    CGContextMoveToPoint(context, 10, 0);
    CGContextAddLineToPoint(context, 95, 0);
    CGContextAddArcToPoint(context, 100, 0, 100, 5, 10);
    CGContextAddLineToPoint(context, 100, 95);
    CGContextAddArcToPoint(context, 100, 100, 95, 100, 10);
    CGContextAddLineToPoint(context, 5, 100);
    CGContextAddArcToPoint(context, 0, 100, 0, 95, 10);
    CGContextAddLineToPoint(context, 0, 5);
    CGContextAddArcToPoint(context, 0, 0, 5, 0, 10);
    CGContextFillPath(context);
}

我通过教程学习到如何绘制一个完美的100像素圆角正方形,但现在我需要一个150像素的正方形!我已经尝试改变所有可能的设置,但结果很奇怪,我无法确定宽度和高度是如何定义的?有人能给予建议吗?


150还是200?我不太清楚。 - Andrea
2
如果这就是你所需要的,那么请参考Simon的答案。该框架为您提供了一切所需。对于更复杂的表单,核心图形可能非常有帮助。当您使用核心图形绘制自己的图形时,我建议使用变量(或常量)例如宽度、高度和conerRadius。首先,它更容易编程。但第二个也是最重要的是它更加灵活。然后,您只需将宽度和高度从100更改为150,就可以了。 - Hermann Klecker
4个回答

13

Swift更新:

以下答案是针对简单用例编写的,当时是正确的。但自那以后,事情发生了很大变化,因此这里提供一个Swift的更新答案。

您可以创建一个UIView扩展,添加方法以圆角化所有角或特定角。将@IBInspectable添加到第一个属性意味着它可以在接口生成器中使用,而不需要代码。

第二个函数比较复杂,不能直接用作@IBInspectable。需要在父视图的viewDidLayoutSubviews中调用它,以确保遮罩在AutoLayout调整内容大小时不会切断内容。

extension UIView {

    @IBInspectable public var cornerRadius: CGFloat {
        set {
            layer.cornerRadius = newValue
        }
        get {
            return layer.cornerRadius
        }
    }

    public func roundCorners(corners: UIRectCorner, radius: CGFloat) {
        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        layer.mask = mask
    }
}

一旦将其添加到您的项目中,您只需执行以下操作:

myView.cornerRadius = 4

or

myView.roundCorners(corners: [.topLeft, .topRight], radius: 4)

非常古老的 Objective-C 回答:

如果您导入了 QuartzCore 框架:

#import <QuartzCore/QuartzCore.h>

如果您想将其添加到项目中,您可以使用以下内容:

UIView *temp = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
temp.layer.cornerRadius = 5;

@SimonMcLoughlin 我同意你的观点! - Andrea
2
@downVoter 能否解释一下?有3个人点赞,还有其他人说这是一个很好的解决方案。当人们在这种情况下投反对票时,我感到很烦恼。显然,你对我的某些代码有问题,我很想知道,这样我就可以像用户一样学习。请分享。 - Simon McLoughlin
2
@Dancer,在这种情况下,使用cornerRadius要容易得多。通常,只有在需要特殊形状、渐变等情况下才使用drawRect。 - Templar
@DarkDust 承认它不适用于更复杂的应用程序。我已经同意Andrea在上面提出的观点。然而,在这种情况下,用户告诉我们他们想要实现什么,并且基于问题中的硬编码示例,我觉得用户需要一个更简单的方法。如果用户想要简单的方法,那么这很好,如果用户想要更高级的方法,那么你的答案是正确的。多个人已经说过了同样的话,所以由用户决定,因为我们没有必要代表他们做出决定所需的信息。 - Simon McLoughlin
感谢大家的帮助 - 澄清一下,我需要使用这个视图来创建一个“祝酒”视图 - 它将包含一个标签和一个图标图片 - 它将用于通知用户他们的进度已经更新 - 在返回到另一个视图之前进行简单的淡入/淡出过程。 - Dancer
显示剩余6条评论

10

如果你必须在 drawRect 中进行绘制,并且其他内容将在未来绘制,则只需使用Bezierpath,否则请参见Simon的答案,了解如何在视图上创建简单的圆角。

- (void)drawRect:(CGRect)rect {
       [super drawRect:rect];
       [[UIColor blueColor] setFill];
       UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect /*CGRectMake(0, 0, 150, 150)*/ cornerRadius:10.0];
       [path fill];
}

5
  1. 将数字转换为变量/常量。

  2. 修改变量/常量的值。

  3. 获得利润!

这是您的代码,已修改以显示我的意思(未经测试):

- (void)drawRect:(CGRect)rect {
    static CGFloat length = 100;
    static CGFloat rounding = 5;

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.1].CGColor);
    CGContextMoveToPoint(context, rounding * 2, 0);
    CGContextAddLineToPoint(context, length - rounding, 0);
    CGContextAddArcToPoint(context, length, 0, length, rounding, rounding * 2);
    CGContextAddLineToPoint(context, length, length - rounding);
    CGContextAddArcToPoint(context, length, length, length - rounding, length, rounding * 2);
    CGContextAddLineToPoint(context, rounding, length);
    CGContextAddArcToPoint(context, 0, length, 0, length - rounding, rounding * 2);
    CGContextAddLineToPoint(context, 0, rounding);
    CGContextAddArcToPoint(context, 0, 0, rounding, 0, rounding * 2);
    CGContextFillPath(context);
}

我也对你代码中的10秒感到困惑。据我所见,它们应该是5秒。无论如何,更简单的解决方案是使用UIBezierPath,就像其他人演示的那样(图层解决方案确实可行,但如果您想在圆角矩形下方绘制某些内容并在其上方绘制其他内容,则显然不起作用)。

3
为什么不使用贝塞尔路径?
CGFloat radius =  4;
CGRect rect = CGRectMake(0,0,200,200);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
[[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.1] setFill];
[path fill];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接