简体   繁体   English

IOS - 绘制圆角正方形

[英]IOS - Drawing rounded corner square

I am trying to create a 200px square with rounded corners to use as an IOS toast style indication.我正在尝试创建一个带圆角的 200 像素正方形,用作 IOS 吐司样式指示。

I have the following so far -到目前为止,我有以下内容-

- (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);
}

I got this far by following a tutorial - it draws a perfect 100px with rounded corners square - but I need a 150px square!我按照教程做到了这一点 - 它绘制了一个完美的 100 像素的圆角正方形 - 但我需要一个 150 像素的正方形! I have changed every setting imaginable - with some bizzare results - but cant work out how the width height is defined!?我已经改变了所有可以想象的设置 - 有一些奇怪的结果 - 但无法弄清楚宽度高度是如何定义的!? Can anyone advise?任何人都可以建议吗?

Update for Swift: Swift 更新:

The below answer was correct that the time it was written for simple use cases.下面的答案是正确的,它是为简单用例编写的。 Things have changed a lot since then so heres an updated answer for swift.从那以后事情发生了很大变化,所以这里有一个 swift 的更新答案。

You can create a UIView extension, to add methods to round all corners, or round specific corners.您可以创建一个 UIView 扩展,以添加圆角或圆角特定角的方法。 Adding @IBInspectable to the first property means it can be used in interface builder without requiring code@IBInspectable添加到第一个属性意味着它可以在不需要代码的情况下在界面构建器中使用

The second function is more complicated and can't be used as an @IBInspectable directly.第二个函数更复杂,不能直接用作@IBInspectable It will need to be called inside the viewDidLayoutSubviews of the parent to ensure the mask doesn't cut off content as AutoLayout grows / shrinks the content.它需要在父视图的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
    }
}

Once added to your project you can simply do:添加到您的项目后,您只需执行以下操作:

myView.cornerRadius = 4

or

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

Very old Objective-c answer:很老的 Objective-c 答案:

If you import QuartzCore framework:如果导入 QuartzCore 框架:

#import <QuartzCore/QuartzCore.h>

and add it to your project, you can use the below:并将其添加到您的项目中,您可以使用以下内容:

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

If you must draw in drawRect and other stuff will be drawn in future, then just use bezierpath, otherwise see Simon's answer for simple rounded corners on a view如果您必须在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];
}
  1. Convert numbers to variables/constants.将数字转换为变量/常量。

  2. Change variables/constants values.更改变量/常量值。

  3. Profit!利润!

Here's your code, modified to show what I mean (untested):这是您的代码,经过修改以显示我的意思(未经测试):

- (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);
}

I also wonder about the 10s in your code.我也想知道你的代码中的 10s。 As far as I can see they should be 5s instead.据我所知,它们应该是 5s。 Anyways, the easier solution is to use a UIBezierPath as others have demonstrated (the layer solution does work, but it obviously won't work if you for example want to draw something below the rounded rect and something above it).无论如何,更简单的解决方案是使用其他人所演示的UIBezierPath (图层解决方案确实有效,但如果您例如想要在圆形矩形下方绘制一些东西而在其上方绘制一些东西,它显然不起作用)。

Why don't you use a bezier path?为什么不使用贝塞尔曲线?

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM