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

Swift自定义圆角箭头绘制问题:设置圆角属性未达预期效果求助

问题根源

你设置的lineCap = .round和lineJoin = .round是描边专用属性,只对路径的线条边缘生效,但你的箭头是靠填充绘制的,这俩属性对填充形状的拐角完全不起作用,所以看不到预期的圆角。

解决办法

要让填充的箭头带圆角,得手动修改路径,给每个拐角加圆弧过渡。下面是改好的代码:

箭头图层配置(简化版)

private let arrowLayer: CAShapeLayer = {
    let layer = CAShapeLayer()
    layer.fillColor = UIColor.orange.cgColor
    layer.anchorPoint = CGPoint(x: 0.2, y: 0.5)
    // 不需要描边的话可以删掉下面两行,保留也不影响填充效果
    layer.lineWidth = 4
    layer.strokeColor = UIColor.orange.cgColor
    return layer
}()

带圆角的路径绘制代码

override func layoutSubviews() {
    super.layoutSubviews()
    let arrowWidth = bounds.width * 0.27
    let arrowHeight = bounds.width * 0.02
    arrowLayer.bounds.size = CGSize(width: arrowWidth, height: arrowHeight)
    arrowLayer.position = CGPoint(x: bounds.midX, y: bounds.midY)
    
    // 圆角半径设为箭头高度的一半,视觉上更协调
    let cornerRadius = arrowHeight * 0.5
    let path = UIBezierPath()
    
    // 先定义箭头的几个关键点位
    let rightTop = CGPoint(x: arrowWidth, y: arrowHeight * 0.3)
    let rightBottom = CGPoint(x: arrowWidth, y: arrowHeight * 0.7)
    let leftBottom = CGPoint(x: 0, y: arrowHeight)
    let leftTop = CGPoint(x: 0, y: 0)
    
    // 从右侧上拐角的圆角起点开始画
    path.move(to: CGPoint(x: rightTop.x - cornerRadius, y: rightTop.y))
    // 画右侧上拐角的圆角
    path.addArc(withCenter: CGPoint(x: rightTop.x, y: rightTop.y + cornerRadius),
                radius: cornerRadius,
                startAngle: .pi * 1.5,
                endAngle: .pi,
                clockwise: false)
    // 连到右侧下拐角的圆角起点
    path.addLine(to: CGPoint(x: rightBottom.x, y: rightBottom.y - cornerRadius))
    // 画右侧下拐角的圆角
    path.addArc(withCenter: CGPoint(x: rightBottom.x, y: rightBottom.y - cornerRadius),
                radius: cornerRadius,
                startAngle: .pi,
                endAngle: .pi * 0.5,
                clockwise: false)
    // 连到左侧下拐角的圆角起点
    path.addLine(to: CGPoint(x: cornerRadius, y: leftBottom.y))
    // 画左侧下拐角的圆角
    path.addArc(withCenter: CGPoint(x: cornerRadius, y: leftBottom.y - cornerRadius),
                radius: cornerRadius,
                startAngle: .pi * 0.5,
                endAngle: 0,
                clockwise: false)
    // 连到左侧上拐角的圆角起点
    path.addLine(to: CGPoint(x: cornerRadius, y: leftTop.y))
    // 画左侧上拐角的圆角
    path.addArc(withCenter: CGPoint(x: cornerRadius, y: leftTop.y + cornerRadius),
                radius: cornerRadius,
                startAngle: 0,
                endAngle: .pi * 1.5,
                clockwise: false)
    // 闭合路径
    path.close()
    
    arrowLayer.path = path.cgPath
}

关键说明

  • 用addArc手动给每个拐角加圆弧,这才是让填充形状带圆角的正确方式
  • 圆角半径跟着箭头高度走,不管箭头尺寸怎么变,圆角比例都自然协调
  • 删掉了没用的lineCap和lineJoin属性,它们对填充形状完全没有效果

内容的提问来源于stack exchange,提问作者Levchenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:54:51