Reputation: 53
I've written following code to draw a rect with a whole in it:
fileprivate let strokeWidth: CGFloat = 5
let shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = UIColor.white.cgColor
shapeLayer.lineWidth = strokeWidth
shapeLayer.fillColor = UIColor(white: 0.5, alpha: 0.9).cgColor
let p = UIBezierPath(rect: bounds.insetBy(dx: -strokeWidth, dy: -strokeWidth))
let radius = bounds.size.width / 3
p.move(to: CGPoint(x: bounds.midX + radius, y: bounds.midY))
p.addArc(withCenter: CGPoint(x: bounds.midX, y: bounds.midY), radius: radius, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: false)
p.close()
shapeLayer.path = p.cgPath
layer.addSublayer(shapeLayer)
The problem here is this line:
p.addArc(withCenter: CGPoint(x: bounds.midX, y: bounds.midY), radius: radius, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: false)
Printing out the description of the path: UIBezierPath: 0x6000000b35c0; MoveTo {-5, -5}, LineTo {380, -5}, LineTo {380, 672}, LineTo {-5, 672}, Close, MoveTo {312.5, 333.5}, LineTo {312.5, 333.49999999999994}, Close
As you can see, the last two entries are lineTo and close, which gives me not the expected result (a full circle), I'll get nothing because the line is too short between 333.5 and 333.4999999.
This problem occurs since switching to Swift 3, in Objective-C this wasn't a problem.
Changing the end angle to 1.9 * Double.pi will also work, no idea why. But the full circle should have 2 * Double.pi.
Any idea or is it a Swift 3 bug?
Upvotes: 2
Views: 3183
Reputation: 236305
Try like this:
let bounds = UIScreen.main.bounds
let strokeWidth: CGFloat = 5
let shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = UIColor.white.cgColor
shapeLayer.lineWidth = strokeWidth
shapeLayer.fillColor = UIColor(white: 0.5, alpha: 0.9).cgColor
let p = UIBezierPath(rect: bounds.insetBy(dx: -strokeWidth, dy: -strokeWidth))
let radius = bounds.size.width / 3
p.move(to: CGPoint(x: bounds.midX + radius, y: bounds.midY))
p.addArc(withCenter: CGPoint(x: bounds.midX, y: bounds.midY), radius: radius, startAngle: 2 * .pi, endAngle: 0, clockwise: false)
p.close()
shapeLayer.fillColor = UIColor.red.cgColor
shapeLayer.strokeColor = UIColor.black.cgColor
shapeLayer.lineWidth = 5
shapeLayer.path = p.cgPath
let view = UIView(frame: bounds)
view.backgroundColor = .yellow
view.layer.addSublayer(shapeLayer)
view
Upvotes: 4