【问题标题】:Draw Rounded Intersect Lines绘制圆角相交线
【发布时间】:2018-09-07 08:49:21
【问题描述】:

我必须创建一个带有按钮和一些自定义边框的选项卡(下图)。问题是我必须为每个相交添加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
    }

这是结果:

如您所见,即使我添加了cornerRadius = 10,它也不起作用。 borderLayer.lineCap = kCALineCapRoundborderLayer.lineJoin = kCALineJoinBevel 也无济于事。

奖金:

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

【问题讨论】:

    标签: ios uikit core-graphics uibezierpath rounded-corners


    【解决方案1】:

    如果您使用UIBezierPath 绘制形状,则设置cornerRadius 不会影响该路径。

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

    例如:

    • 绿色虚线是tabFrame
    • pt1 是 tabFrame 的“left”和“top + 10”(你的半径)
    • pt2是tabFrame的“left + 10”和“top”
    • 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

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

    【讨论】: