How to draw a just the corners of a rectangle (without lines connecting them)
Here's a custom UIView
class that draws itself with the four corners. You can set various properties to get the look you need.
class CornerRect: UIView {
var color = UIColor.black {
didSet {
setNeedsDisplay()
}
}
var radius: CGFloat = 5 {
didSet {
setNeedsDisplay()
}
}
var thickness: CGFloat = 2 {
didSet {
setNeedsDisplay()
}
}
var length: CGFloat = 30 {
didSet {
setNeedsDisplay()
}
}
override func draw(_ rect: CGRect) {
color.set()
let t2 = thickness / 2
let path = UIBezierPath()
// Top left
path.move(to: CGPoint(x: t2, y: length + radius + t2))
path.addLine(to: CGPoint(x: t2, y: radius + t2))
path.addArc(withCenter: CGPoint(x: radius + t2, y: radius + t2), radius: radius, startAngle: CGFloat.pi, endAngle: CGFloat.pi * 3 / 2, clockwise: true)
path.addLine(to: CGPoint(x: length + radius + t2, y: t2))
// Top right
path.move(to: CGPoint(x: frame.width - t2, y: length + radius + t2))
path.addLine(to: CGPoint(x: frame.width - t2, y: radius + t2))
path.addArc(withCenter: CGPoint(x: frame.width - radius - t2, y: radius + t2), radius: radius, startAngle: 0, endAngle: CGFloat.pi * 3 / 2, clockwise: false)
path.addLine(to: CGPoint(x: frame.width - length - radius - t2, y: t2))
// Bottom left
path.move(to: CGPoint(x: t2, y: frame.height - length - radius - t2))
path.addLine(to: CGPoint(x: t2, y: frame.height - radius - t2))
path.addArc(withCenter: CGPoint(x: radius + t2, y: frame.height - radius - t2), radius: radius, startAngle: CGFloat.pi, endAngle: CGFloat.pi / 2, clockwise: false)
path.addLine(to: CGPoint(x: length + radius + t2, y: frame.height - t2))
// Bottom right
path.move(to: CGPoint(x: frame.width - t2, y: frame.height - length - radius - t2))
path.addLine(to: CGPoint(x: frame.width - t2, y: frame.height - radius - t2))
path.addArc(withCenter: CGPoint(x: frame.width - radius - t2, y: frame.height - radius - t2), radius: radius, startAngle: 0, endAngle: CGFloat.pi / 2, clockwise: true)
path.addLine(to: CGPoint(x: frame.width - length - radius - t2, y: frame.height - t2))
path.lineWidth = thickness
path.stroke()
}
}
Sample usage:
let cr = CornerRect(frame: CGRect(x: 0, y: 0, width: 300, height: 500))
cr.color = .yellow
cr.thickness = 5
cr.backgroundColor = .white
Copy and paste that into a playground. Try different values for the properties.
custom view - rounding rectangle's corners drawn by lines
When drawing an arc, you need to specify the full bounding box for that arc, and the start and sweep angle. I try to see them visually, like so:
E.g. when going clock wise, the start angle is positioned 180degrees from the origin. And from the startAngle, if you sweep 90 degrees clock wise, you'll end up at the desired end position.
Take note where the origin, startAngle and sweepAngle are in this graphic.
In kotlin, it can look something like this:
// Given some radius, viewWidth and viewHeight
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
path.apply {
moveTo(radius, 0F)
lineTo(viewWidth - radius, 0F)
arcTo(viewWidth - 2 * radius, 0F, viewWidth, 2 * radius, -90F, 90F, false)
lineTo(viewWidth, radius)
arcTo(viewWidth - 2 * radius, viewHeight - 2 * radius, viewWidth, viewHeight, 0F, 90F, false)
lineTo(radius, viewHeight)
arcTo(0F, viewHeight - 2 * radius, 2 * radius, viewHeight, 90F, 90F, false)
lineTo(0F, radius)
arcTo(0F, 0F, 2 * radius, 2 * radius, 180F, 90F, false)
}
canvas?.drawPath(path, linePaint)
}
And the result will be something like this:
Draw only corner of a rectangle
You can draw it by yourself by DrawLine
function in Paint
event handler, something like this:
Pen pen = new Pen(Color.Red);
private void Form1_Load(object sender, System.EventArgs e)
{
pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
}
private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawLine(pen, 0, 0, pictureBox1.Right, 0);
g.DrawLine(pen, 0, 0, 0, pictureBox1.Bottom);
}
It's a use case, maybe you need other coordinates, but you can fix it easily.
How to use android canvas to draw a Rectangle with only topleft and topright corners round?
You can draw that piece by piece using drawLine()
and drawArc()
functions from the Canvas
.
How do I draw a rounded rectangle without filling it (in MFC)?
Just select a NULL brush before drawing the rounded rectangle, like
CPen pen;
CBrush* pOldBrush;
CPen* pOldPen;
if (!pen.CreatePenIndirect(&m_logpen))
return;
pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
pOldPen = pDC->SelectObject(&pen);
pDC->RoundRect(m_rect, m_roundness);
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
Drawing Rounded Corners Using UIBezierPath
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()
Related Topics
Return Uiimage Array from Parse Query Block
How to Use Tap Gesture in Accessibility in Swift
How to Update Individual Array Element in Firebase with iOS Swift
How to Change Uiwebview Orientation Programmatically in Swift
Indexing into Array of Functions: Expression Resolves to an Unused L-Value
Replace C Style For-Loop in Swift 2.2.1
Pure Swiftui Login, Signup, Register Flow, Is It Possible
Nsexceptionallowsinsecurehttploads Not Working for Ip Addresses
Uitapgesturerecognizer Called Immediately
Swift 3 - Passing Data Between a View Controller and After That to Another 2
iOS Development App Startup Crash
How to Debug Swift Playgroundbook
Give Thumbnail Image with Uiactivityviewcontroller
Target Is Not Found, Please Reconnect the Device, Xcode:Device Support File
Change Buttonstyle Modifier Based on Light or Dark Mode in Swiftui