I want to get a rectangle with rounded upper corners. For it, I use UIBezierPath
and CAShapeLayer
.
The problem is that the left corner is rounded correctly, and the right corner is not, and I do not understand why this is happening, what I am doing wrong.
It is important for me to make the current code effective, the solution of the problem through a cornerRadius
or in other ways, unfortunately, does not interest me.
Current result image
and
Required result image .
import UIKit
func getRadians(from degrees: CGFloat) -> CGFloat {
return degrees * CGFloat.pi / 180
}
let view = UIView()
view.backgroundColor = .green
let width: CGFloat = 800
let height: CGFloat = 400
view.frame = CGRect(x: 0, y: 0, width: width, height: height)
let cornersRadius: CGFloat = 100
var path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: width, y: 0))
path.addLine(to: CGPoint(x: width, y: height))
path.addLine(to: CGPoint(x: 0, y: height))
path.addLine(to: CGPoint(x: 0, y: 0))
path = path.reversing()
let topLeft = UIBezierPath()
topLeft.move(to: CGPoint(x: 0, y: cornersRadius))
topLeft.addLine(to: CGPoint(x: 0, y: 0))
topLeft.addLine(to: CGPoint(x: cornersRadius, y: 0))
topLeft.addArc(withCenter: CGPoint(x: cornersRadius, y: cornersRadius), radius: cornersRadius, startAngle: getRadians(from: 270), endAngle: getRadians(from: 180), clockwise: false)
topLeft
let topRight = UIBezierPath()
topRight.move(to: CGPoint(x: width, y: cornersRadius))
topRight.addLine(to: CGPoint(x: width, y: 0))
topRight.addLine(to: CGPoint(x: width - cornersRadius, y: 0))
topRight.addArc(withCenter: CGPoint(x: width - cornersRadius, y: cornersRadius), radius: cornersRadius, startAngle: getRadians(from: 270), endAngle: getRadians(from: 0), clockwise: true)
topRight
path.append(topLeft)
path.append(topRight)
let layer = CAShapeLayer()
layer.path = path.cgPath
view.layer.mask = layer
view
There is a simpler way to achieve it. You can use the following method:
init(roundedRect:byRoundingCorners:cornerRadii:)
for UIBezierPath
More info on it in Apple documentation
let cornerRadius = CGFloat(10.0)
let roundedCorners = roundedCorners.union([.topLeft, .topRight])
let path = UIBezierPath(roundedRect:maskRect, byRoundingCorners:roundedCorners, cornerRadii: CGSize(width: cornerRadius, height: cornerRadius))
let maskLayer = CAShapeLayer()
maskLayer.frame = YOUR_VIEW_TO_MASK.bounds
maskLayer.path = maskPath.cgPath
YOUR_VIEW_TO_MASK.layer.mask = maskLayer
Use a single UIBezierPath:
let largeRadius: CGFloat = 100.0
let smallRadius: CGFloat = 12.0
let path = UIBezierPath()
// Bottom left
path.move(to: CGPoint(x: 0, y: height - smallRadius)
path.addLine(to: CGPoint(x: 0, y: largeRadius)
// Top left
path.addArc(withCenter: CGPoint(x: largeRadius, y: largeRadius), radius: largeRadius, startAngle: getRadians(from: 270), endAngle: getRadians(from: 0, clockwise: true))
// Top right
path.addLine(to: CGPoint(x: width - largeRadius, y: 0)
path.addArc(withCenter: CGPoint(x: width - largeRadius, y: largeRadius), radius: largeRadius, startAngle: getRadians(from: 0), endAngle: getRadians(from: 90))
// EITHER (rounded bottom corners):
// Bottom right
path.addLine(to: CGPoint(x: width, y: height - smallRadius)
path.addArc(withCenter: CGPoint(x: width - smallRadius, y: height - smallRadius), radius: smallRadius, startAngle: getRadians(from: 90), endAngle: getRadians(from: 180))
// Bottom left
path.addLine(to: CGPoint(x: smallRadius, y: height - smallRadius))
path.addArc(withCenter: CGPoint(x: smallRadius, y: height - smallRadius), radius: smallRadius, startAngle: getRadians(from: 180), endAngle: getRadians(from: 270))
// OR (square bottom corners):
// Bottom right
path.addLine(to: CGPoint(x: width, y: height))
// Bottom left
path.addLine(to: CGPoint(x: 0, y: height))
path.close()
let layer = CAShapeLayer()
layer.path = path.cgPath
Note this code provides both a method to add the smaller rounded corners at the bottom rather than using a separate layer mask, as well as using square bottom corners.
I'm also making assumptions about your getRadians()
function.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.