如何使用倾斜渐变填充CAShapeLayer

时间:2016-12-07 14:14:38

标签: ios swift optimization uibezierpath cashapelayer

如何使用渐变和45度角填充library(RMySQL) con_str <- "MySQL(), user = 'root', password = '', dbname = 'nepal_statagri', host = 'localhost'" (this is the string I want to pass as a parameter to RScript) mysqlconnection = dbConnect(con_str)

例如,在图片1 中,下面的代码绘制一个正方形并填充蓝色图层(CAShapeLayer())。

但是,我如何用蓝色到红色的45度角填充它,如图像2 (即UIColor.blueColor().CGColorUIColor.blueColor().CGColor)?

代码:

UIColor.redColor().CGColor

Solid-color square next to square with gradient

4 个答案:

答案 0 :(得分:29)

为什么不使用具有CAGradientLayerstartPoint属性的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

注意:为圆圈添加了贝塞尔曲线路径,因为它可以在没有方形掩码的情况下工作。

答案 1 :(得分:5)

轻松将渐变应用于CALayer

Swift 4.2,Xcode 10.0

虽然上述解决方案仅在像 45°这样的微小角度上确实有效,但是我的代码却能够将梯度设置为任意给定角度。

public extension CALayer {

    public func applyGradient(of colors: UIColor..., atAngle angle: CGFloat) -> CAGradientLayer {
        let gradient = CAGradientLayer()
        gradient.frame = frame
        gradient.colors = colors
        gradient.calculatePoints(for: angle)
        gradient.mask = self
        return gradient
    }

}


public extension CAGradientLayer {

    /// Sets the start and end points on a gradient layer for a given angle.
    ///
    /// - Important:
    /// *0°* is a horizontal gradient from left to right.
    ///
    /// With a positive input, the rotational direction is clockwise.
    ///
    ///    * An input of *400°* will have the same output as an input of *40°*
    ///
    /// With a negative input, the rotational direction is clockwise.
    ///
    ///    * An input of *-15°* will have the same output as *345°*
    ///
    /// - Parameters:
    ///     - angle: The angle of the gradient.
    ///
    public func calculatePoints(for angle: CGFloat) {


        var ang = (-angle).truncatingRemainder(dividingBy: 360)

        if ang < 0 { ang = 360 + ang }

        let n: CGFloat = 0.5

        let tanx: (CGFloat) -> CGFloat = { tan($0 * CGFloat.pi / 180) }

        switch ang {

        case 0...45, 315...360:
            let a = CGPoint(x: 0, y: n * tanx(ang) + n)
            let b = CGPoint(x: 1, y: n * tanx(-ang) + n)
            startPoint = a
            endPoint = b

        case 45...135:
            let a = CGPoint(x: n * tanx(ang - 90) + n, y: 1)
            let b = CGPoint(x: n * tanx(-ang - 90) + n, y: 0)
            startPoint = a
            endPoint = b

        case 135...225:
            let a = CGPoint(x: 1, y: n * tanx(-ang) + n)
            let b = CGPoint(x: 0, y: n * tanx(ang) + n)
            startPoint = a
            endPoint = b

        case 225...315:
            let a = CGPoint(x: n * tanx(-ang - 90) + n, y: 0)
            let b = CGPoint(x: n * tanx(ang - 90) + n, y: 1)
            startPoint = a
            endPoint = b

        default:
            let a = CGPoint(x: 0, y: n)
            let b = CGPoint(x: 1, y: n)
            startPoint = a
            endPoint = b

        }
    }

}

用法:

let layer = CAShapeLayer()

// Setup layer...

// Gradient Direction: →
let gradientLayer1 = layer.applyGradient(of: UIColor.yellow, UIColor.red, at: 0)

// Gradient Direction: ↗︎
let gradientLayer2 = layer.applyGradient(of: UIColor.purple, UIColor.yellow, UIColor.green, at: -45)

// Gradient Direction: ←
let gradientLayer3 = layer.applyGradient(of: UIColor.yellow, UIColor.blue, UIColor.green, at: 180)

// Gradient Direction: ↓
let gradientLayer4 = layer.applyGradient(of: UIColor.red, UIColor.blue, at: 450)

数学解释

所以我实际上最近才花了很多时间自己回答这个问题。以下是一些示例角度,仅用于帮助理解和可视化顺时针旋转方向。

Example Angles

如果您对我的计算方式感兴趣,我制作了一张桌子,从本质上可视化了- 360°的工作。

Table

答案 2 :(得分:2)

我认为是

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)

答案 3 :(得分:0)