Как заполнить CAShapeLayer с угловым градиентом?

вопрос:

как мне заполнить CAShapeLayer() с градиентом и под углом 45 градусов?

например,Фото 1, приведенный ниже код рисует квадрат и заполняет слой синим цветом (UIColor.blueColor().CGColor).

но, как я могу заполнить его градиентом на 45 градусов от синего до красного, как в Рисунок 2 (т. е. UIColor.blueColor().CGColor в UIColor.redColor().CGColor)?

код:

let path = UIBezierPath()
path.moveToPoint(CGPoint(x: 0, y: 0))
path.addLineToPoint(CGPoint(x: 0, y: 100))
path.addLineToPoint(CGPoint(x: 100, y: 100))
path.addLineToPoint(CGPoint(x: 100, y: 0))
path.closePath()

let shape = CAShapeLayer()
shape.path = path.CGPath
shape.fillColor = UIColor.blueColor().CGColor

enter image description here

3 ответов


Почему бы не использовать CAGradientLayer имеющего startPoint и endPoint свойства.

вы можете сделать:

import UIKit
import PlaygroundSupport

let frame = CGRect(x: 0, y: 0, width: 100, height: 100)
let view = UIView(frame: frame)

PlaygroundPage.current.liveView = view

let path = UIBezierPath(ovalIn: frame)

let shape = CAShapeLayer()
shape.frame = frame
shape.path = path.cgPath
shape.fillColor = UIColor.blue.cgColor

let gradient = CAGradientLayer()
gradient.frame = frame
gradient.colors = [UIColor.blue.cgColor,
                   UIColor.red.cgColor]
gradient.startPoint = CGPoint(x: 0, y: 1)
gradient.endPoint = CGPoint(x: 1, y: 0)
gradient.mask = shape

view.layer.addSublayer(gradient)

enter image description here

Примечание: добавлен путь Безье для круга, потому что он будет работать без маски для квадрата.


Я думаю, что это

shape.startPoint = CGPoint(x: 1.0, y: 0.0)
shape.endPoint = CGPoint(x: 0.0, y: 1.0)

, который является первым цветом внизу справа на второй цвет вверху слева. Если вы хотите, чтобы первый цвет в правом верхнем углу и второй цвет в левом нижнем углу, то вы должны иметь

shape.startPoint = CGPoint(x: 1.0, y: 1.0)
shape.endPoint = CGPoint(x: 0.0, y: 0.0)

первый цвет вверху слева, второй цвет внизу справа

shape.startPoint = NSMakePoint(x: 0.0, y: 1.0)
shape.endPoint = NSMakePoint(x: 1.0, y: 0.0)

первый цвет внизу слева, второй цвет вверху справа

shape.startPoint = CGPoint(x: 0.0, y: 0.0)
shape.endPoint = CGPoint(x: 1.0, y: 1.0)

@Alistra ответ работает, если у вас есть ваша форма в верхнем левом углу экрана. Если вы попытаетесь переместить местоположение своей фигуры, вы заметите, что фигура обрезается (если она вообще появляется в зависимости от ваших значений x и y)

чтобы исправить это, используйте два разных фрейма как для градиентного слоя, так и для слоя формы. Установите x,y координаты вашего слоя формы в 0,0. Затем установите x,y координаты вашего градиентного слоя туда, куда вы хотите он располагался на экране.

    let gradientFrame = CGRect(x: 100,
                               y: 150,
                               width: 150,
                               height: 150)
    let circleFrame = CGRect(x: 0,
                             y: 0,
                             width: 150,
                             height: 150)
    let circle = CAShapeLayer()
    circle.frame = circleFrame
    circle.path = UIBezierPath(ovalIn: circleFrame).cgPath

    let gradient = CAGradientLayer()
    gradient.frame = gradientFrame
    gradient.startPoint = CGPoint(x: 0, y: 0)
    gradient.endPoint = CGPoint(x: 1, y: 1)
    gradient.colors = [UIColor.blue.cgColor,
                       UIColor.red.cgColor]
    gradient.mask = circle
    view.layer.addSublayer(gradient)