Sto tentando di disegnare il gradiente angolare utilizzando CaGradientLayer
. So che l'angolo può essere definito utilizzando startPoint
e endPoint
. Posso calcolare questi punti per alcuni angoli standard come 0, 90, 180, 360 ecc. Ma voglio formulare questi punti per l'angolo arbitrario. Ho provato a calcolarlo usando un po 'di trigonometria, ma non ho avuto alcun successo. Qualcuno può darmi qualche indicazione su come calcolare questi punti per gli angoli arbitrari?Definizione dell'angolo del gradiente utilizzando CAGradientLayer
risposta
Ecco un metodo che crea una vista che consente la rotazione di 360 gradi del suo gradiente a due colori in base all'input da un cursore (o altro). Il valore del cursore in entrata (variabile "x" sotto) è compreso tra 0.0 e 1.0.
A 0,0 il gradiente è orizzontale (con il colore A in alto e il colore B in basso), ruotando di 360 gradi sul valore 1.0 (identico al valore 0.0 - o una rotazione completa).
E.g. quando x = 0,25, il colore A è lasciato e il colore B è giusto. A 0.5, il colore A è inferiore e il colore B è sopra, 0,75 il colore A è giusto e il colore B è lasciato. Ruota in senso antiorario da destra a sinistra.
Sono necessari quattro argomenti: frame, colore A, coloreB e il valore di input (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;
}
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)
}
Questo è fortemente basato sulla soluzione Sarthak Sharmas. Ho fatto un'estensione di UIView e ho pensato che le conversioni di leggibilità e di tipo potrebbe essere migliorata un po ':
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)
}
}
Aggiungi ad un nuovo o un file Swift correlato e tutto quello che dovete fare è chiamare o myView.setGradient(colors: gradientColorsArray)
o myView.setGradient(colors: gradientColorsArray, angle: 90)
.
'CAGradientLayer' supporta solo i gradienti assiali (direzionali). –
@ DavidRönnqvist Lo so. Non sto parlando di gradienti radiali. Sto cercando di dare un angolo al gradiente assiale. – blancos
Quindi stai chiedendo della trigonometria per capire i due punti dati da un angolo? –