绘制圆角相交线

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了绘制圆角相交线相关的知识,希望对你有一定的参考价值。

我必须创建一个带有按钮和一些自定义边框的选项卡(下图)。问题是我必须为每个交叉点添加cornerRadius但我不确定如何正确地执行它。

我有这个代码来绘制带边框的标签:

private func drawBorder(selectedTab: UIButton) {
        // The Tab frame (below one)
        guard let tabContainerFrame = vTabContainer?.frame else { return }

        let borderColor = selectedTab.titleColor(for: .selected)

        let tabFrame = selectedTab.convert(selectedTab.bounds, to: self)
        let topMargin: CGFloat = 5
        let tabOrigin = CGPoint(x: tabFrame.origin.x, y: tabFrame.origin.y - topMargin)

        // Make paths to draw
        let path = UIBezierPath()

        path.move(to: tabOrigin) // Origin (top left)
        path.addLine(to: CGPoint(x: tabFrame.maxX, y: tabOrigin.y)) // -> right
        path.addLine(to: CGPoint(x: tabFrame.maxX, y: tabFrame.maxY)) // -> down

        if tabFrame.maxX != tabContainerFrame.maxX {
            path.addLine(to: CGPoint(x: tabContainerFrame.maxX, y: tabContainerFrame.origin.y)) // -> right
        }

        path.addLine(to: CGPoint(x: tabContainerFrame.maxX, y: tabContainerFrame.maxY)) // -> Down
        path.addLine(to: CGPoint(x: tabContainerFrame.origin.x, y: tabContainerFrame.maxY)) // -> left
        path.addLine(to: CGPoint(x: tabContainerFrame.origin.x, y: tabContainerFrame.origin.y)) // -> up

        if tabOrigin.x != tabContainerFrame.origin.x {
            path.addLine(to: CGPoint(x: tabOrigin.x, y: tabContainerFrame.origin.y)) // -> right
        }

        // Close the path. This will create the last line automatically.
        path.close()

        // Draw
        let borderLayer = CAShapeLayer()
        borderLayer.path = path.cgPath
        borderLayer.lineCap = kCALineCapRound
        borderLayer.lineJoin = kCALineJoinBevel
        borderLayer.fillColor = UIColor.clear.cgColor
        borderLayer.strokeColor = borderColor?.cgColor
        borderLayer.cornerRadius = 10
        borderLayer.lineWidth = 2
        layer.addSublayer(borderLayer)

        self.borderLayer = borderLayer
    }

这是结果:

Tab1 Tab2

正如你所看到的,即使我添加cornerRadius = 10,它也无法正常工作。 borderLayer.lineCap = kCALineCapRoundborderLayer.lineJoin = kCALineJoinBevel也没有帮助。

奖金:

我想有办法实现动态@IBInspectable var lineCornerRadius: CGFloat = 10

答案

如果使用UIBezierPath绘制形状,则设置cornerRadius将不会对该路径产生任何影响。

相反,你想使用path.addCurve(to: ...)来制作你的圆角。

例如:

enter image description here

  • 绿色虚线是tabFrame
  • pt1是tabFrame的“left”和“top + 10”(你的半径)
  • pt2是tabFrame的“左+ 10”和“顶部”
  • pt3是第一个曲线的第二个“控制点” - tabFrame的左上角
  • pt4是tabFrame的“右 - 10”和“顶部”
  • pt5是tabFrame的“右”和“顶+10”
  • pt6是第二条曲线的第二个“控制点” - tabFrame的右上角

所以

path.addCurve(to: pt2, controlPoint1: pt1, controlPoint2: pt3)

添加曲线到pt2 ...来自pt1 ...与曲线控制点pt3

然后:

path.addLine(to: pt4)

从当前点(pt2)添加一条线到pt4

然后:

path.addCurve(to: pt5, controlPoint1: pt4, controlPoint2: pt6)

添加曲线到pt5 ...来自pt4 ...与曲线控制点pt6

你的形状的其余部分是正常的线段。

以上是关于绘制圆角相交线的主要内容,如果未能解决你的问题,请参考以下文章

Python:用相交线计算形状中的特定子形状

Android UI绘制圆角矩形进度条 ① ( 像素值转化 dp -> px | Paint 标志位设置 | Paint 画笔线帽样式设置 | Paint 画笔线段连接处样式设置 )

在片段着色器中绘制别名像素完美线?

带有圆角而不是 100% 屏幕宽度的自定义片段对话框

圆角关于圆角imageview,下面这种效果怎么实现

Cesium绘制点、线、面、圆、矩形