Как заставить CAGradientLayer следовать CGPath - PullRequest
0 голосов
/ 05 октября 2018

Учитывая CAShapeLayer, определяющий путь, как на рисунке ниже, я хочу добавить CAGradientLayer, который следует по пути слоя формы.

Например, учитывая градиент от черного-> красного:

  • верхний правый закругленный элемент будет черным,
  • , а если ползунок будет на 100, верхний левый будет красным,
  • , и если ползунок будет на 50тогда половина ползунка будет черной (как показано ниже), а видимый градиент из черного (справа вверху) перейдет в красно-черный внизу

The Green should become the gradient

Каждый предыдущий пост, который я нашел, на самом деле не отвечает на этот вопрос.Например, поскольку я могу добавить только осевые CAGradientLayers, я могу это сделать (рис. Ниже), но вы можете видеть, что это не правильно (верхний левый конец снова становится черным).Как заставить градиент на самом деле следовать пути / маске

enter image description here

Ответы [ 2 ]

0 голосов
/ 06 октября 2018

Любой на iOS 12 должен согласиться с предложением Мэтта или, возможно, использовать SFProgressCircle, как предложил DonMag.

Мое решение: я лично добавил два CAShapeLayers, каждый с соответствующим CAGradientLayer.

Byпрограммно разделив ползунок пополам, как на картинке ниже, я смог применить градиент сверху вниз с каждой стороны, что дает эффект, который я ищу.Он невидим для пользователя.

enter image description here

0 голосов
/ 05 октября 2018

Для простой круговой формы новый конический градиент великолепен.Я смог получить это немедленно (это слой конического градиента, замаскированный слоем в форме круга):

enter image description here

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

class MyGradientView : UIView {
    override class var layerClass : AnyClass { return CAGradientLayer.self }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder:aDecoder)
        let lay = self.layer as! CAGradientLayer
        lay.type = .conic
        lay.startPoint = CGPoint(x:0.5,y:0.5)
        lay.endPoint = CGPoint(x:0.5,y:0)
        lay.colors = [UIColor.green.cgColor, UIColor.red.cgColor]
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        let shape = CAShapeLayer()
        shape.frame = self.bounds
        shape.strokeColor = UIColor.black.cgColor
        shape.fillColor = UIColor.clear.cgColor
        let b = UIBezierPath(ovalIn: shape.frame.inset(by: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)))
        shape.path = b.cgPath
        shape.lineWidth = 10
        shape.lineCap = .round
        shape.strokeStart = 0.1
        shape.strokeEnd = 0.9
        shape.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        shape.transform = CATransform3DMakeRotation(-.pi/2, 0, 0, 1)
        self.layer.mask = shape
    }
}
...