使用CAGradientLayer定义渐变的角度

16

我正在尝试使用 CaGradientLayer 绘制角度渐变。我知道可以使用 startPointendPoint 来定义角度。对于一些标准的角度,如0、90、180、360等,我可以计算这些点。但是我想为任意角度制定这些点。我尝试使用一些三角学计算它,但没有成功。有人可以给我指引如何为任意角度计算这些点吗?


CAGradientLayer 仅支持轴向(方向性)渐变。 - David Rönnqvist
@DavidRönnqvist 我知道。我不是在谈论径向渐变。我试图给轴向渐变指定角度。 - blancos
那么你是在询问如何使用三角函数来找出给定一个角度的两个点? - David Rönnqvist
@DavidRönnqvist 是的,完全正确。 - blancos
3个回答

14

Swift 3

static func setGradient(view: UIView!,viewRadius: CGFloat!, color1: UIColor!, color2: UIColor!, angle: Double!, alphaValue: CGFloat!){
    let gradient = CAGradientLayer()
    
    gradient.frame =  CGRect(origin: CGPoint.zero, size: view.frame.size)
    
    gradient.colors = [color1.withAlphaComponent(alphaValue).cgColor, color2.withAlphaComponent(alphaValue).cgColor]
    let x: Double! = angle / 360.0
    let a = pow(sinf(Float(2.0 * M_PI * ((x + 0.75) / 2.0))),2.0);
    let b = pow(sinf(Float(2*M_PI*((x+0.0)/2))),2);
    let c = pow(sinf(Float(2*M_PI*((x+0.25)/2))),2);
    let d = pow(sinf(Float(2*M_PI*((x+0.5)/2))),2);
    
    gradient.endPoint = CGPoint(x: CGFloat(c),y: CGFloat(d))
    gradient.startPoint = CGPoint(x: CGFloat(a),y:CGFloat(b))
    
    view.roundCorners([.topLeft, .bottomLeft], radius: viewRadius)
    view.layer.insertSublayer(gradient, at: 0)
    
    
}

我得到了起点(2.2799733224976824e-14, 0.4999999701976776),终点(1.0, 0.4999999701976776),对于90度你能再检查一下吗? - venky

9

这是基于Sarthak Sharma的解决方案而来。我扩展了UIView,并且发现可读性和类型转换可以有所改进:

extension UIView {

    func setGradient(colors: [CGColor], angle: Float = 0) {
        let gradientLayerView: UIView = UIView(frame: CGRect(x:0, y: 0, width: bounds.width, height: bounds.height))
        let gradient: CAGradientLayer = CAGradientLayer()
        gradient.frame = gradientLayerView.bounds
        gradient.colors = colors

        let alpha: Float = angle / 360
        let startPointX = powf(
            sinf(2 * Float.pi * ((alpha + 0.75) / 2)),
            2
        )
        let startPointY = powf(
            sinf(2 * Float.pi * ((alpha + 0) / 2)),
            2
        )
        let endPointX = powf(
            sinf(2 * Float.pi * ((alpha + 0.25) / 2)),
            2
        )
        let endPointY = powf(
            sinf(2 * Float.pi * ((alpha + 0.5) / 2)),
            2
        )

        gradient.endPoint = CGPoint(x: CGFloat(endPointX),y: CGFloat(endPointY))
        gradient.startPoint = CGPoint(x: CGFloat(startPointX), y: CGFloat(startPointY))

        gradientLayerView.layer.insertSublayer(gradient, at: 0)
        layer.insertSublayer(gradientLayerView.layer, at: 0)
    }

}

将以下代码添加到新的或相关的Swift文件中,然后您只需调用myView.setGradient(colors: gradientColorsArray)myView.setGradient(colors: gradientColorsArray, angle: 90)即可。


1
在(alpha + X)中,X的值代表什么? - Pawan Kumar
我得到了起点(2.2799733224976824e-14, 0.4999999701976776),终点(1.0, 0.4999999701976776),角度为90。 - venky

7
这是一种创建视图的方法,它允许基于滑块(或其他任何输入)进行两种颜色渐变的360度旋转。传入的滑块值(下面的“x”变量)在0.0和1.0之间。
在0.0时,渐变为水平(颜色A在上方,颜色B在下方),通过360度旋转到值1.0(与值0.0相同-或完整旋转)。
例如,当x = 0.25时,颜色A在左侧,颜色B在右侧。当x = 0.5时,颜色A在下方,颜色B在上方,在0.75处,颜色A在右侧,颜色B在左侧。它逆时针从右向左旋转。
它需要四个参数:框架、颜色A、颜色B和输入值(0-1)。
-(UIView *)gradientViewWithFrame:(CGRect)frame colourA:(UIColor *)A colourB:(UIColor *)B rotation:(float)x {

//x is between 0 and 1, eg. from a slider, representing 0 - 360 degrees
//colour A starts on top, with colour B below
//rotations move anti-clockwise

//1. create the colour view
UIView * colourView = [UIView new];
colourView.frame = frame;

//2. create the gradient layer
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = colourView.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[A CGColor], (id)[B CGColor], nil];
[colourView.layer insertSublayer:gradient atIndex:0];

//3. create coordinates
float a = pow(sinf((2*M_PI*((x+0.75)/2))),2);
float b = pow(sinf((2*M_PI*((x+0.0)/2))),2);
float c = pow(sinf((2*M_PI*((x+0.25)/2))),2);
float d = pow(sinf((2*M_PI*((x+0.5)/2))),2);

//4. set the gradient direction
[gradient setStartPoint:CGPointMake(a, b)];
[gradient setEndPoint:CGPointMake(c, d)];

return colourView;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接