Azi*_*ode 14 ios uibezierpath swift
我设法创造圆角,但我遇到第一个圆角(右下角)的问题
题 :
这是我的自定义矩形代码和截图:
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()
Run Code Online (Sandbox Code Playgroud)
mat*_*att 18
我认为你所做的事情过于复杂.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)
Run Code Online (Sandbox Code Playgroud)
Rob*_*Rob 14
几个观察:
确保您获取视图bounds
并将其插入线宽的一半。这确保了整个描边边框落在bounds
视图的范围内。如果您的线宽为 1,这可能不那么明显,但是如果线宽更大,问题就会变得更加明显。
如果使用draw(_:)
方法,请不要使用rect
传递给此方法的 ,而是参考bounds
(插图,如上所述)。该CGRect
传递给draw(_:)
正在绘制的矩形,不一定全面bounds
。(通常是,但并非总是如此,所以总是引用bounds
视图的 ,而不是rect
传递给此方法的。)
正如文档所说(强调):
需要更新的视图边界部分。第一次绘制视图时,此矩形通常是视图的整个可见边界。但是,在后续的绘制操作中,矩形可能仅指定视图的一部分。
我会给视图的所有各种属性一个didSet
观察者,它将触发视图重绘。这样,任何 IB 覆盖或以编程方式设置的值都将自动反映在结果视图中。
如果你愿意,你可以制作整个东西@IBDesignable
并制作 properties @IBInspectable
,所以你可以在 Interface Builder 中看到它的呈现。这不是必需的,但如果您想在故事板或 NIB 中看到它的呈现,它会很有用。
虽然您可以使用圆弧圆角,但使用四边形曲线更容易,恕我直言。您只需指定圆弧的结束位置和矩形的角,二次贝塞尔曲线将产生一个很好的圆角。使用这种技术,不需要计算角度或圆弧的中心。
因此:
@IBDesignable
class BubbleView: UIView {
@IBInspectable var lineWidth: CGFloat = 1 { didSet { setNeedsDisplay() } }
@IBInspectable var cornerRadius: CGFloat = 10 { didSet { setNeedsDisplay() } }
@IBInspectable var calloutSize: CGFloat = 5 { didSet { setNeedsDisplay() } }
@IBInspectable var fillColor: UIColor = .yellow { didSet { setNeedsDisplay() } }
@IBInspectable var strokeColor: UIColor = .black { didSet { setNeedsDisplay() } }
override func draw(_ rect: CGRect) {
let rect = bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2)
let path = UIBezierPath()
// lower left corner
path.move(to: CGPoint(x: rect.minX + cornerRadius, y: rect.maxY - calloutSize))
path.addQuadCurve(to: CGPoint(x: rect.minX, y: rect.maxY - calloutSize - cornerRadius),
controlPoint: CGPoint(x: rect.minX, y: rect.maxY - calloutSize))
// left
path.addLine(to: CGPoint(x: rect.minX, y: rect.minY + cornerRadius))
// upper left corner
path.addQuadCurve(to: CGPoint(x: rect.minX + cornerRadius, y: rect.minY),
controlPoint: CGPoint(x: rect.minX, y: rect.minY))
// top
path.addLine(to: CGPoint(x: rect.maxX - cornerRadius, y: rect.minY))
// upper right corner
path.addQuadCurve(to: CGPoint(x: rect.maxX, y: rect.minY + cornerRadius),
controlPoint: CGPoint(x: rect.maxX, y: rect.minY))
// right
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY - calloutSize - cornerRadius))
// lower right corner
path.addQuadCurve(to: CGPoint(x: rect.maxX - cornerRadius, y: rect.maxY - calloutSize),
controlPoint: CGPoint(x: rect.maxX, y: rect.maxY - calloutSize))
// bottom (including callout)
path.addLine(to: CGPoint(x: rect.midX + calloutSize, y: rect.maxY - calloutSize))
path.addLine(to: CGPoint(x: rect.midX, y: rect.maxY))
path.addLine(to: CGPoint(x: rect.midX - calloutSize, y: rect.maxY - calloutSize))
path.close()
fillColor.setFill()
path.fill()
strokeColor.setStroke()
path.lineWidth = lineWidth
path.stroke()
}
}
Run Code Online (Sandbox Code Playgroud)
这产生:
没关系,我实际上找到了解决方案.
而不是用直线启动代码:
path.moveToPoint(CGPoint(x: 300, y: 0))
Run Code Online (Sandbox Code Playgroud)
我改为以弧形开始(右上角):
path.addArcWithCenter(CGPoint(x: 300-10, y: 50), radius: 10 , startAngle: 0 , endAngle: CGFloat(M_PI/2) , clockwise: true) //1st rounded corner
Run Code Online (Sandbox Code Playgroud)
通过这样做,我有四个圆角,我只需要在代码的末尾添加一条直线:
path.closePath()
Run Code Online (Sandbox Code Playgroud)
这是代码和截图:
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()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8127 次 |
最近记录: |