I have a design element that I'm having trouble figuring out; hoping someone may be able to point me in the right direction. The element I am trying to build is like so;
Effectively, it's a rounded rectangle with a stroke on the left, top, and right sides (the bottom should have no stroke).
I've dabbled in using the following code;
// Create the rounded rectangle
let maskPath = UIBezierPath(roundedRect: myView.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 4.0, height: 4.0))
// Setup a shape layer
let shape = CAShapeLayer()
// Create the shape path
shape.path = maskPath.cgPath
// Apply the mask
myView.layer.mask = shape
Subsequently, I'm using the following to draw the stroke around the rect;
// Add border
let borderLayer = CAShapeLayer()
borderLayer.path = maskPath.cgPath
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.strokeColor = UIColor.white.cgColor
borderLayer.lineWidth = 2.0
borderLayer.frame = self.bounds
self.layer.addSublayer(borderLayer)
This results in the following image;
I've not been able to figure out how to either remove the bottom stroke or draw the item using a UIBezierPath(), but rounding the corners in a way that would be identical to the rounded rect (I'm using another rounded rect in the same view for a different purpose, and the rounded corners would need to be identical).
Thanks!
Don't use a shape layer. Use a layer (or a view). Draw the UIBezierPath's path into it and stroke it, and then erase the bottom line by drawing it and stroking it with a .clear
blend mode.
Result:
Code (modify as desired; I use here a clear UIView that draws the shape as its draw
code):
let p = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: [.topLeft, .topRight],
cornerRadii: CGSize(width: 4.0, height: 4.0))
UIColor.white.setStroke()
p.stroke()
let p2 = UIBezierPath()
p2.move(to: CGPoint(x:0, y:self.bounds.height))
p2.addLine(to: CGPoint(x:self.bounds.width, y:self.bounds.height))
p2.lineWidth = 2
p2.stroke(with: .clear, alpha: 1)
EDIT Another way would have been to clip out the bottom line area before drawing the rounded rect:
let p1 = UIBezierPath(rect: CGRect(origin:.zero,
size:CGSize(width:self.bounds.width, height:self.bounds.height-2)))
p1.addClip()
let p = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: [.topLeft, .topRight],
cornerRadii: CGSize(width: 4.0, height: 4.0))
UIColor.white.setStroke()
p.stroke()