如何使用Swift绘制仅含四角(无边框连线)的CGRect图形?
实现仅显示四角的矩形(Swift)
嘿,这个需求我刚好在项目里折腾过,用Swift实现起来挺顺手的,给你两种常用方案,按需挑就行~
方案一:自定义UIView,重写draw(_:)方法
这种方式适合静态展示的场景,直接在View的绘制周期里画出四个角的短线段,代码简洁直观。
完整代码示例
import UIKit class CornerOnlyView: UIView { // 可自定义的属性:角短线长度、线宽、颜色 var cornerLength: CGFloat = 16.0 { didSet { setNeedsDisplay() } } var lineWidth: CGFloat = 2.0 { didSet { setNeedsDisplay() } } var cornerColor: UIColor = .black { didSet { setNeedsDisplay() } } override func draw(_ rect: CGRect) { super.draw(rect) guard let context = UIGraphicsGetCurrentContext() else { return } // 配置线条样式 context.setStrokeColor(cornerColor.cgColor) context.setLineWidth(lineWidth) // 让线段端点更圆润,可选.square或者.round context.setLineCap(.round) // 绘制左上角:水平向右 + 垂直向下 context.move(to: CGPoint(x: rect.minX, y: rect.minY)) context.addLine(to: CGPoint(x: rect.minX + cornerLength, y: rect.minY)) context.move(to: CGPoint(x: rect.minX, y: rect.minY)) context.addLine(to: CGPoint(x: rect.minX, y: rect.minY + cornerLength)) // 绘制右上角:水平向左 + 垂直向下 context.move(to: CGPoint(x: rect.maxX, y: rect.minY)) context.addLine(to: CGPoint(x: rect.maxX - cornerLength, y: rect.minY)) context.move(to: CGPoint(x: rect.maxX, y: rect.minY)) context.addLine(to: CGPoint(x: rect.maxX, y: rect.minY + cornerLength)) // 绘制左下角:水平向右 + 垂直向上 context.move(to: CGPoint(x: rect.minX, y: rect.maxY)) context.addLine(to: CGPoint(x: rect.minX + cornerLength, y: rect.maxY)) context.move(to: CGPoint(x: rect.minX, y: rect.maxY)) context.addLine(to: CGPoint(x: rect.minX, y: rect.maxY - cornerLength)) // 绘制右下角:水平向左 + 垂直向上 context.move(to: CGPoint(x: rect.maxX, y: rect.maxY)) context.addLine(to: CGPoint(x: rect.maxX - cornerLength, y: rect.maxY)) context.move(to: CGPoint(x: rect.maxX, y: rect.maxY)) context.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY - cornerLength)) // 执行绘制 context.strokePath() } }
使用方式
在ViewController里直接添加这个View,支持frame或AutoLayout布局:
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white let cornerView = CornerOnlyView() cornerView.cornerColor = .systemBlue cornerView.cornerLength = 20 cornerView.lineWidth = 3 cornerView.frame = CGRect(x: 50, y: 100, width: 200, height: 150) view.addSubview(cornerView) // 如果用AutoLayout,取消下面的注释: // cornerView.translatesAutoresizingMaskIntoConstraints = false // NSLayoutConstraint.activate([ // cornerView.centerXAnchor.constraint(equalTo: view.centerXAnchor), // cornerView.centerYAnchor.constraint(equalTo: view.centerYAnchor), // cornerView.widthAnchor.constraint(equalToConstant: 200), // cornerView.heightAnchor.constraint(equalToConstant: 150) // ]) } }
方案二:使用CAShapeLayer(支持动画,更灵活)
如果需要给角做动画效果,或者不想自定义View,可以用CAShapeLayer创建四个角的路径,再添加到目标View的layer上。
代码示例
import UIKit extension UIView { func addCornerOnlyBorder(cornerLength: CGFloat = 16, lineWidth: CGFloat = 2, color: UIColor = .black) { // 先移除已有的角边框layer,避免重复添加 layer.sublayers?.filter { $0.name == "cornerBorderLayer" }.forEach { $0.removeFromSuperlayer() } let cornerLayer = CAShapeLayer() cornerLayer.name = "cornerBorderLayer" cornerLayer.strokeColor = color.cgColor cornerLayer.lineWidth = lineWidth cornerLayer.lineCap = .round cornerLayer.fillColor = UIColor.clear.cgColor let path = UIBezierPath() // 绘制四个角的路径 path.move(to: CGPoint(x: bounds.minX, y: bounds.minY)) path.addLine(to: CGPoint(x: bounds.minX + cornerLength, y: bounds.minY)) path.move(to: CGPoint(x: bounds.minX, y: bounds.minY)) path.addLine(to: CGPoint(x: bounds.minX, y: bounds.minY + cornerLength)) path.move(to: CGPoint(x: bounds.maxX, y: bounds.minY)) path.addLine(to: CGPoint(x: bounds.maxX - cornerLength, y: bounds.minY)) path.move(to: CGPoint(x: bounds.maxX, y: bounds.minY)) path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY + cornerLength)) path.move(to: CGPoint(x: bounds.minX, y: bounds.maxY)) path.addLine(to: CGPoint(x: bounds.minX + cornerLength, y: bounds.maxY)) path.move(to: CGPoint(x: bounds.minX, y: bounds.maxY)) path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY - cornerLength)) path.move(to: CGPoint(x: bounds.maxX, y: bounds.maxY)) path.addLine(to: CGPoint(x: bounds.maxX - cornerLength, y: bounds.maxY)) path.move(to: CGPoint(x: bounds.maxX, y: bounds.maxY)) path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY - cornerLength)) cornerLayer.path = path.cgPath layer.addSublayer(cornerLayer) } }
使用方式
给任意UIView直接调用这个扩展方法即可:
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white let targetView = UIView(frame: CGRect(x: 50, y: 100, width: 200, height: 150)) targetView.backgroundColor = .lightGray view.addSubview(targetView) // 添加四角边框 targetView.addCornerOnlyBorder(cornerLength: 20, lineWidth: 3, color: .systemRed) // 如果View的frame会动态变化,记得在`layoutSubviews`里重新调用这个方法 } }
小提示
- 如果用AutoLayout,记得在View的
layoutSubviews方法里重新触发绘制(方案一)或重新添加layer(方案二),不然View尺寸变化时,四角位置会错位。 - 线宽较粗时,线条会居中绘制,可能超出View边界,给View设置
clipsToBounds = true就能解决,或者把绘制起点往外偏移lineWidth/2。
内容的提问来源于stack exchange,提问作者coder
相关产品推荐
相关产品推荐

