如何向UIBezierPath自定义矩形添加圆角?

时间:2023-02-09 23:59:56

I managed to create the rounded corners, but I'm having trouble with the first rounded corner (lower right )

我成功地创建了圆角,但是我在第一个圆角上遇到了麻烦(右下角)

Question :

问题:

  • Can I add an (addArcWithCenter) method before the ( moveToPoint ) method ?
  • 我可以在(moveToPoint)方法之前添加一个(addArcWithCenter)方法吗?
  • How can i get rid of the straight line at the beginning of the rectangle (lower right) ?
  • 如何去掉矩形开头的直线(右下角)?

here is my code for the custom rectangle and a screenshot :

这是我的自定义矩形代码和屏幕截图:

let path = UIBezierPath()
path.moveToPoint(CGPoint(x: 300, y: 0))
path.addArcWithCenter(CGPoint(x: 300-10, y: 50), radius: 10 , startAngle: 0 , endAngle: CGFloat(M_PI/2)  , clockwise: true) //1st rounded corner
path.addArcWithCenter(CGPoint(x: 200, y: 50), radius:10, startAngle: CGFloat(2 * M_PI / 3), endAngle:CGFloat(M_PI) , clockwise: true)// 2rd rounded corner
path.addArcWithCenter(CGPoint(x: 200, y: 10), radius:10, startAngle: CGFloat(M_PI), endAngle:CGFloat(3 * M_PI / 2), clockwise: true)// 3rd rounded corner
// little triangle at the bottom
path.addLineToPoint(CGPoint(x:240 , y:0))
path.addLineToPoint(CGPoint(x: 245, y: -10))
path.addLineToPoint(CGPoint(x:250, y: 0))
path.addArcWithCenter(CGPoint(x: 290, y: 10), radius: 10, startAngle: CGFloat(3 * M_PI / 2), endAngle: CGFloat(2 * M_PI ), clockwise: true)
path.closePath()

如何向UIBezierPath自定义矩形添加圆角?

3 个解决方案

#1


16  

I think what you're doing is overly complicated. UIBezierPath gives you UIBezierPath(roundedRect:) so why not use it? Stroke the rounded rectangle; erase the spot where you're going to put the little triangle; add the triangle; fill the compound path; and stroke the missing two sides of the triangle. Like this (this is just some code I happened to have lying around - you should change the numbers to fit your shape, of course):

我觉得你做的事情太复杂了。UIBezierPath给了你UIBezierPath(roundedRect:)为什么不使用它呢?中风圆角矩形;擦掉这个小三角形的位置;添加三角形;填充复合路径;划掉三角形缺失的两边。就像这样(这只是我偶然发现的一些代码-你应该改变数字来适应你的形状):

let con = UIGraphicsGetCurrentContext()
CGContextTranslateCTM(con, 10, 10)
UIColor.blueColor().setStroke()
UIColor.blueColor().colorWithAlphaComponent(0.4).setFill()
let p = UIBezierPath(roundedRect: CGRectMake(0,0,250,180), cornerRadius: 10)
p.stroke()
CGContextClearRect(con, CGRectMake(20,170,10,11))
let pts = [
    CGPointMake(20,180), CGPointMake(20,200),
    CGPointMake(20,200), CGPointMake(30,180)
]
p.moveToPoint(pts[0])
p.addLineToPoint(pts[1])
p.addLineToPoint(pts[3])
p.fill()
CGContextStrokeLineSegments(con, pts, 4)

如何向UIBezierPath自定义矩形添加圆角?

#2


5  

Nevermind, I actually found the solution.

没关系,我找到解决办法了。

Instead of starting the code with a straight line :

而不是以直线开始代码:

path.moveToPoint(CGPoint(x: 300, y: 0))

I instead start with an arc (upper right):

我用一个圆弧(右上角)开始:

path.addArcWithCenter(CGPoint(x: 300-10, y: 50), radius: 10 , startAngle: 0 , endAngle: CGFloat(M_PI/2)  , clockwise: true) //1st rounded corner

and by doing this, I have four rounded corners and I just need to add a straight line at the end of the code right before:

通过这样做,我有了四个圆角我只需要在前面的代码末尾添加一条直线:

path.closePath()  

Here is the code and a screenshot:

这里是代码和屏幕截图:

let path = UIBezierPath()
path.addArcWithCenter(CGPoint(x: 300-10, y: 50), radius: 10 , startAngle: 0 , endAngle: CGFloat(M_PI/2)  , clockwise: true) //1st rounded corner
path.addArcWithCenter(CGPoint(x: 200, y: 50), radius:10, startAngle: CGFloat(2 * M_PI / 3), endAngle:CGFloat(M_PI) , clockwise: true)// 2rd rounded corner
path.addArcWithCenter(CGPoint(x: 200, y: 10), radius:10, startAngle: CGFloat(M_PI), endAngle:CGFloat(3 * M_PI / 2), clockwise: true)// 3rd rounded corner
// little triangle
path.addLineToPoint(CGPoint(x:240 , y:0))
path.addLineToPoint(CGPoint(x: 245, y: -10))
path.addLineToPoint(CGPoint(x:250, y: 0))
path.addArcWithCenter(CGPoint(x: 290, y: 10), radius: 10, startAngle: CGFloat(3 * M_PI / 2), endAngle: CGFloat(2 * M_PI ), clockwise: true)
path.addLineToPoint(CGPoint(x:300 , y:50))
path.closePath()

如何向UIBezierPath自定义矩形添加圆角?

#3


1  

You can't do this automatically. You have to make the lines shorter and then use arcs of the radius that you want the corner radius to be.

你不能自动这么做。你必须使直线变短,然后用你想要的角半径的弧。

So. Instead of adding a line to x,y you add the line to x-radius, y. Then add the arc. Then the next line starts at x, y+radius.

所以。不给x加上一条线,而是把这条线加到x-radius y上,然后加上圆弧。然后下一行从x y+半径开始。

#1


16  

I think what you're doing is overly complicated. UIBezierPath gives you UIBezierPath(roundedRect:) so why not use it? Stroke the rounded rectangle; erase the spot where you're going to put the little triangle; add the triangle; fill the compound path; and stroke the missing two sides of the triangle. Like this (this is just some code I happened to have lying around - you should change the numbers to fit your shape, of course):

我觉得你做的事情太复杂了。UIBezierPath给了你UIBezierPath(roundedRect:)为什么不使用它呢?中风圆角矩形;擦掉这个小三角形的位置;添加三角形;填充复合路径;划掉三角形缺失的两边。就像这样(这只是我偶然发现的一些代码-你应该改变数字来适应你的形状):

let con = UIGraphicsGetCurrentContext()
CGContextTranslateCTM(con, 10, 10)
UIColor.blueColor().setStroke()
UIColor.blueColor().colorWithAlphaComponent(0.4).setFill()
let p = UIBezierPath(roundedRect: CGRectMake(0,0,250,180), cornerRadius: 10)
p.stroke()
CGContextClearRect(con, CGRectMake(20,170,10,11))
let pts = [
    CGPointMake(20,180), CGPointMake(20,200),
    CGPointMake(20,200), CGPointMake(30,180)
]
p.moveToPoint(pts[0])
p.addLineToPoint(pts[1])
p.addLineToPoint(pts[3])
p.fill()
CGContextStrokeLineSegments(con, pts, 4)

如何向UIBezierPath自定义矩形添加圆角?

#2


5  

Nevermind, I actually found the solution.

没关系,我找到解决办法了。

Instead of starting the code with a straight line :

而不是以直线开始代码:

path.moveToPoint(CGPoint(x: 300, y: 0))

I instead start with an arc (upper right):

我用一个圆弧(右上角)开始:

path.addArcWithCenter(CGPoint(x: 300-10, y: 50), radius: 10 , startAngle: 0 , endAngle: CGFloat(M_PI/2)  , clockwise: true) //1st rounded corner

and by doing this, I have four rounded corners and I just need to add a straight line at the end of the code right before:

通过这样做,我有了四个圆角我只需要在前面的代码末尾添加一条直线:

path.closePath()  

Here is the code and a screenshot:

这里是代码和屏幕截图:

let path = UIBezierPath()
path.addArcWithCenter(CGPoint(x: 300-10, y: 50), radius: 10 , startAngle: 0 , endAngle: CGFloat(M_PI/2)  , clockwise: true) //1st rounded corner
path.addArcWithCenter(CGPoint(x: 200, y: 50), radius:10, startAngle: CGFloat(2 * M_PI / 3), endAngle:CGFloat(M_PI) , clockwise: true)// 2rd rounded corner
path.addArcWithCenter(CGPoint(x: 200, y: 10), radius:10, startAngle: CGFloat(M_PI), endAngle:CGFloat(3 * M_PI / 2), clockwise: true)// 3rd rounded corner
// little triangle
path.addLineToPoint(CGPoint(x:240 , y:0))
path.addLineToPoint(CGPoint(x: 245, y: -10))
path.addLineToPoint(CGPoint(x:250, y: 0))
path.addArcWithCenter(CGPoint(x: 290, y: 10), radius: 10, startAngle: CGFloat(3 * M_PI / 2), endAngle: CGFloat(2 * M_PI ), clockwise: true)
path.addLineToPoint(CGPoint(x:300 , y:50))
path.closePath()

如何向UIBezierPath自定义矩形添加圆角?

#3


1  

You can't do this automatically. You have to make the lines shorter and then use arcs of the radius that you want the corner radius to be.

你不能自动这么做。你必须使直线变短,然后用你想要的角半径的弧。

So. Instead of adding a line to x,y you add the line to x-radius, y. Then add the arc. Then the next line starts at x, y+radius.

所以。不给x加上一条线,而是把这条线加到x-radius y上,然后加上圆弧。然后下一行从x y+半径开始。