Нарисуйте скругленные пересекающиеся линии - PullRequest
0 голосов
/ 07 сентября 2018

Мне нужно создать вкладку с кнопками и некоторой пользовательской рамкой (изображения ниже). Проблема в том, что я должен добавить 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 = kCALineCapRound и borderLayer.lineJoin = kCALineJoinBevel тоже не помогают.

Бонус:

Я бы хотел иметь способ реализации динамического @IBInspectable var lineCornerRadius: CGFloat = 10.

1 Ответ

0 голосов
/ 07 сентября 2018

Если вы используете UIBezierPath для рисования фигуры, настройка cornerRadius не будет влиять на этот путь.

Вместо этого вы хотите использовать path.addCurve(to: ...), чтобы сделать закругленные углы.

Например:

enter image description here

  • зеленая пунктирная линия - это tabFrame
  • pt1 - это "left" и "top + 10" tabFrame (ваш радиус)
  • pt2 - это "left + 10" и "top" tabFrame
  • pt3 - вторая «контрольная точка» первой кривой - верхний левый угол tabFrame
  • pt4 - это "правильная - 10" и "верхняя часть" tabFrame
  • pt5 - это "right" и "top + 10" tabFrame
  • pt6 - вторая «контрольная точка» второй кривой - верхний правый угол tabFrame

So

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

Остальная часть вашей фигуры - это нормальные отрезки.

...