I'm working with 2 UIBezierPath
to create a rectangle and a semicircle shape. It works fine but I am not able to fill the intersection with color.
That's my drawCircle
and my addPaths
functions:
private func drawCircle(selectedPosition: SelectionRangePosition, currentMonth: Bool) {
circleView.layer.sublayers = nil
let radius = contentView.bounds.height/2
let arcCenter = CGPoint(x: ceil(contentView.bounds.width/2), y: ceil(contentView.bounds.height/2))
let circlePath = UIBezierPath(arcCenter: arcCenter, radius: radius, startAngle: .pi/2, endAngle: .pi * 3/2, clockwise: selectedPosition == .left)
let semiCircleLayerPath = UIBezierPath()
let semiCircleLayer = CAShapeLayer()
semiCircleLayer.fillColor = UIColor.tealish.cgColor
circleView.layer.addSublayer(semiCircleLayer)
switch (selectedPosition, currentMonth) {
case (.left, true):
let rectanglePath = UIBezierPath(rect: CGRect(x: contentView.bounds.width / 2, y: 0, width: ceil(contentView.bounds.width / 2), height: contentView.bounds.height))
addPaths(semiCircleLayerPath, rectanglePath, circlePath, semiCircleLayer)
case (.middle, true):
backgroundColor = .tealish
case (.right, true):
// Note: The + 10 is just to overlap the shapes and test if the filling works
let rectanglePath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: ceil(contentView.bounds.width / 2) + 10, height: contentView.bounds.height))
addPaths(semiCircleLayerPath, rectanglePath, circlePath, semiCircleLayer)
default:
backgroundColor = .clear
}
}
private func addPaths(_ semiCircleLayerPath: UIBezierPath, _ rectanglePath: UIBezierPath, _ circlePath: UIBezierPath, _ semiCircleLayer: CAShapeLayer) {
semiCircleLayerPath.append(circlePath)
semiCircleLayerPath.append(rectanglePath)
semiCircleLayer.path = semiCircleLayerPath.cgPath
}
The problem is that the semicircle path and the rectangle path are being added in opposite directions. This is a function of the way the Cocoa API adds them, unfortunately; in your case, it means that the intersection has a "wrap count" of 0.
Fortunately, there is an easy fix: create separate paths for the semicircle and the rectangle. When fill them both individually, you should get your desired result.
Unfortunately, this will mean that you can't use layer drawing only: you will want to use the drawRect method to draw the background.
If your dates are separate UILabels, you can skip this rendering & path filling problem entirely by dropping a UIView as a child of the calendar, under the labels holding the dates; give it a background color & rounded corners (using layer.cornerRadius
as usual). That'll take care of your rounded rect for you.
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.