Ios 将线性渐变应用于线段(UIBezierPath)

Ios 将线性渐变应用于线段(UIBezierPath),ios,swift,linear-gradients,cagradientlayer,radial-gradients,Ios,Swift,Linear Gradients,Cagradientlayer,Radial Gradients,我指的是一个(已解决的),因为它提出了一个新问题: 现在我有了线性渐变,但我无法使它从饼图段(UIBezierPath)的中心开始,并在另一侧结束 也许我应该从中心开始做一个径向梯度,我不关心任何部分,我只是把它应用在遮罩上,它应该会起作用。但是我认为应该有一种方法将线性渐变应用到视图中的特定帧,并将起点和终点设置到该帧。问题是,它不去的方式,我想当试图插入角度 这就是我得到的: 有人知道我应该如何更改我的CAGradientLayer以获得从中心开始到弧(对侧)结束的线性渐变吗?渐变。起点和

我指的是一个(已解决的),因为它提出了一个新问题:

现在我有了线性渐变,但我无法使它从饼图段(UIBezierPath)的中心开始,并在另一侧结束

也许我应该从中心开始做一个径向梯度,我不关心任何部分,我只是把它应用在遮罩上,它应该会起作用。但是我认为应该有一种方法将线性渐变应用到视图中的特定帧,并将起点和终点设置到该帧。问题是,它不去的方式,我想当试图插入角度

这就是我得到的:


有人知道我应该如何更改我的
CAGradientLayer
以获得从中心开始到弧(对侧)结束的线性渐变吗?

渐变。起点和渐变。终点定义为:

该点在单位坐标空间中定义,然后在绘制时映射到图层的边界矩形

你想要:

grad.startPoint = CGPoint(x: center.x/self.bounds.width, y: center.y/self.bounds.height)
grad.endPoint = CGPoint(x: (center.x+(cos(myStartAngle)* finalRadius))/self.bounds.width, y: (center.y+(sin(myStartAngle)* finalRadius))/self.bounds.height)
顺便说一句:调试这个的一个很好的方法是注释掉
grad.mask=mask
,这样你就可以看到整个渐变,以及开始/结束是如何工作的

这里是一个游乐场的代码,如果你仍然有困难让它工作

//: Playground - noun: a place where people can play

import UIKit
import QuartzCore

class Arc: UIView {
    public override init(frame: CGRect) {
        super.init(frame:frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        if let context = UIGraphicsGetCurrentContext() {
            let myBezier = UIBezierPath()
            let center = CGPoint(x:80, y:140)
            let r: CGFloat = 450
            myBezier.move(to: center)
            myBezier.addArc(withCenter: center, radius: r, startAngle: 0.1, endAngle: 0.5, clockwise: true)
            myBezier.close()
            UIColor.blue.setFill()
            myBezier.fill()
            context.addPath(myBezier.cgPath)
            context.clip()
            let shape = CAShapeLayer()
            shape.frame = self.bounds
            shape.path = myBezier.cgPath
            shape.strokeColor = UIColor.red.cgColor
            shape.lineWidth = 0.5
            shape.fillColor = nil

            let grad = CAGradientLayer()
            grad.frame = self.bounds // I tried here myBezier.bounds without any success (I don't see any gradient)
            grad.colors = [UIColor.black.cgColor, UIColor.white.cgColor]

            grad.startPoint = CGPoint(x: center.x/self.bounds.width, y: center.y/self.bounds.height)
            grad.endPoint = CGPoint(x: (center.x+(cos(0.1)*r))/self.bounds.width, y: (center.y+(sin(0.1)*r))/self.bounds.height)

            let mask = CAShapeLayer()
            mask.frame = self.bounds
            mask.path = myBezier.cgPath
            mask.fillColor = UIColor.black.cgColor
            grad.mask = mask

            self.layer.addSublayer(grad)
            self.layer.addSublayer(shape)
        }
    }
}

let v = Arc(frame: CGRect(x: 0, y: 0, width: 600, height: 600))
v.backgroundColor = .green

grad.startPoint
grad.endPoint
定义为:

该点在单位坐标空间中定义,然后在绘制时映射到图层的边界矩形

你想要:

grad.startPoint = CGPoint(x: center.x/self.bounds.width, y: center.y/self.bounds.height)
grad.endPoint = CGPoint(x: (center.x+(cos(myStartAngle)* finalRadius))/self.bounds.width, y: (center.y+(sin(myStartAngle)* finalRadius))/self.bounds.height)
顺便说一句:调试这个的一个很好的方法是注释掉
grad.mask=mask
,这样你就可以看到整个渐变,以及开始/结束是如何工作的

这里是一个游乐场的代码,如果你仍然有困难让它工作

//: Playground - noun: a place where people can play

import UIKit
import QuartzCore

class Arc: UIView {
    public override init(frame: CGRect) {
        super.init(frame:frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        if let context = UIGraphicsGetCurrentContext() {
            let myBezier = UIBezierPath()
            let center = CGPoint(x:80, y:140)
            let r: CGFloat = 450
            myBezier.move(to: center)
            myBezier.addArc(withCenter: center, radius: r, startAngle: 0.1, endAngle: 0.5, clockwise: true)
            myBezier.close()
            UIColor.blue.setFill()
            myBezier.fill()
            context.addPath(myBezier.cgPath)
            context.clip()
            let shape = CAShapeLayer()
            shape.frame = self.bounds
            shape.path = myBezier.cgPath
            shape.strokeColor = UIColor.red.cgColor
            shape.lineWidth = 0.5
            shape.fillColor = nil

            let grad = CAGradientLayer()
            grad.frame = self.bounds // I tried here myBezier.bounds without any success (I don't see any gradient)
            grad.colors = [UIColor.black.cgColor, UIColor.white.cgColor]

            grad.startPoint = CGPoint(x: center.x/self.bounds.width, y: center.y/self.bounds.height)
            grad.endPoint = CGPoint(x: (center.x+(cos(0.1)*r))/self.bounds.width, y: (center.y+(sin(0.1)*r))/self.bounds.height)

            let mask = CAShapeLayer()
            mask.frame = self.bounds
            mask.path = myBezier.cgPath
            mask.fillColor = UIColor.black.cgColor
            grad.mask = mask

            self.layer.addSublayer(grad)
            self.layer.addSublayer(shape)
        }
    }
}

let v = Arc(frame: CGRect(x: 0, y: 0, width: 600, height: 600))
v.backgroundColor = .green