Нарисуйте линию с градиентом, используя NSBezierPath, CAShapeLayer и CAGradientLayer - PullRequest
0 голосов
/ 09 мая 2020

У меня есть приложение для macOS, в котором я рисую линии и другие фигуры.

Я использую NSBezierPath для формирования линий или фигур, а затем добавляю его в путь CAShapeLayer и, наконец, добавляю CAShapeLayer в представление.

Все работает нормально, и у меня один цвет обводки. Однако я хочу, чтобы линии / цифры не были одного цвета, а были нескольких цветов (градиент). Я знаю, что это можно сделать с помощью CAGradientLayer, и попробовал несколько примеров из других вопросов SO, показывающих iOS варианты, но у меня они не работали.

Ниже приведен фрагмент кода из приложения:

startPoint = point

currentPath = NSBezierPath()
currentShape = CAShapeLayer()

currentShape?.lineWidth = lineWeight
currentShape?.strokeColor = strokeColor.cgColor
currentShape?.fillColor = fillColor.cgColor

currentShape?.lineJoin = CAShapeLayerLineJoin.round
currentShape?.lineCap = CAShapeLayerLineCap.round

currentPath?.move(to: point)
currentPath?.line(to: point)

currentShape?.path = currentPath?.cgPath

view.layer?.addSublayer(currentShape!)

currentGradient = CAGradientLayer()
currentGradient?.mask = currentShape
currentGradient?.frame = currentShape!.frame
currentGradient?.colors = [NSColor.red.cgColor, NSColor.black.cgColor]

view.layer?.addSublayer(currentGradient!)

// some more code here that I omitted (to draw shapes with NSBezierPath)

if let shape = currentShape {
    shape.path = currentPath?.cgPath
    currentGradient?.mask = shape
    currentGradient?.frame = shape.frame
}

Если я удалю код, включающий currentGradient, я вижу линии / фигуры (в одном цвете solid), но когда я добавляю часть градиента, я ничего не вижу. Что я делаю неправильно в приведенном выше коде?

Любая помощь или подсказки были бы очень признательны.

1 Ответ

1 голос
/ 09 мая 2020

Если вы искали, то вы знаете ответ. Вы не можете обводить фигуру градиентом. Вместо этого вы маскируете в градиент; слой формы становится маской, посредством которой открывается слой градиента. Пример (v - вид в окне):

    let grad = CAGradientLayer()
    grad.frame = v.bounds
    v.layer?.addSublayer(grad)
    grad.colors = [NSColor.red.cgColor, NSColor.blue.cgColor]
    let shape = CAShapeLayer()
    shape.frame = v.bounds
    shape.lineWidth = 3
    shape.fillColor = NSColor.clear.cgColor
    shape.strokeColor = NSColor.black.cgColor
    let path = CGPath(ellipseIn: v.bounds.insetBy(dx: 4, dy: 4), transform: nil)
    shape.path = path
    grad.mask = shape

enter image description here

...