You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:05:36