十八.核心动画 - 使用CAGradientLayer图层构建渐变视图

引言

在现代的UI设计中,渐变色和圆角已经成为了不可或缺的元素。无论是应用程序的背景,按钮,还是图标,这些设计趋势不仅使界面更加美观,还能提升用户体验。特别是渐变色,它通过颜色的平滑过渡,赋予了界面更多的层次感和动感。

然而,直接使用CAGradientLayer图层来实现这些渐变效果,在布局和代码编写上会显得繁琐复杂。这时,创建一个渐变视图组件就显得尤为重要。通过封装CAGradientLayer,我们可以更高效地管理和复用渐变效果,从而提升开发效率。

CAGradientLayer简介

其实在前面的博客中我们已经对CAGradientLayer做了一些介绍,在这里我们再简单的概况一下它的基本属性和使用方法。

CAGradientLayer常用的属性

  • colors:[Ant]?类型,在OC中是id类型的数组,意味着我们可以放任何值,但是事实上它需要的是一个CGColorRef类型的数组,指定了渐变的颜色,默认值nil。
  • locations:[NSNumber]?类型,每个元素的取值范围是0到1,它定义了每个颜色在渐变中的具体位置,通过这些位置,我们可以控制颜色如何在视图中分布和过渡。
  • startPoint:CGPoint类型,渐变开始点需要和endPoint共同作用来定义渐变的方向,比如startPoint是[0.5,0],endPoint是[0.5,1]那么意味着从上往下渐变。
  • endPoint:CGPoint类型,渐变结束的点。
  • type:CAGradientLayerType类型,一共有三个值axial(线性渐变),radial(径向渐变),conic(圆锥渐变)

最常用的就是axial,也是默认值,当我们修改type为其它属性时,记得一定需要设置locations及startPoint和endPoint属性,不然看不见效果奥!

CAGradientLayer基本用法

设置type为.axial:

        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        gradientLayer.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
        // 设置渐变颜色的分布位置
        gradientLayer.locations = [0.0, 1.0]
        // 可选:设置渐变的起点和终点
        gradientLayer.startPoint = CGPoint(x: 0.5, y: 0) //顶部中点
        gradientLayer.endPoint = CGPoint(x: 0.5, y: 1.0)   // 底部中点
        gradientLayer.type = .axial
        self.layer.addSublayer(gradientLayer)

我们设置了颜色为红色和蓝色两种颜色,每个颜色的位置是视图的开始和结束,那么意味着将从中心点开始渐变。

而颜色渐变的方向是从上到下,渐变的方式为线性渐变。

效果如下:

  • 设置type为.radial:

  •         let gradientLayer = CAGradientLayer()
            gradientLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
            gradientLayer.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
            // 设置渐变颜色的分布位置
            gradientLayer.locations = [0.0, 1.0]
            // 可选:设置渐变的起点和终点
            gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.5) //中点
            gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)   //右下角
            gradientLayer.type = .radial
            self.layer.addSublayer(gradientLayer)
    

    这次我们修改了type,并且设置开始点为中心点,颜色将呈圆形扩散,扩散的结束点为右下角。

  • 效果如下:

设置type为.conic:

        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        gradientLayer.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
        // 设置渐变颜色的分布位置
        gradientLayer.locations = [0.0, 1.0]
        // 可选:设置渐变的起点和终点
        gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.5) //中点
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)   //右下角
        gradientLayer.type = .conic
        self.layer.addSublayer(gradientLayer)

我们设置旋转的中心点为视图的中心点,半径为视图中心点到右下角的距离,而开始位置则是中心点到右下角这一条线,顺时针旋转渐变,效果如下:

创建渐变视图

下面我们就来创建一个通用渐变视图组件,我们可以像其它UIView的视图一样来使用它。

1.创建PHGradientView

首先继承自UIView创建一个名为PHGradientView的视图,并为其添加一个渐变图层。

class PHGradientView: UIView {
    /// 渐变图层
    private let gradientLayer = CAGradientLayer()


    override init(frame: CGRect) {
        super.init(frame: frame)
        self.layer.addSublayer(gradientLayer)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        gradientLayer.frame = self.bounds
    }

}

2.定义常用类型的枚举

在实际开发中常用的渐变都是线性渐变,从左到右或者从上到下,我们将其定义为不同类型的枚举:

enum PHGradientDirection {
    /// 从左到右
    case leftToRight
    /// 从上到下
    case topToBottom
    /// 从左上到右下
    case topLeftToBottomRight
    /// 从右上到左下
    case topRightToBottomLeft
}

3.自定义初始化方法

为视图添加自定义的初始化方法,可以创建最常用的渐变视图,该方法提供了两个必传参数,和两个可选参数。

    /// 自定义初始化方法 默认从左到右
    /// - Parameters:
    /// - startColor: 开始颜色
    /// - endColor: 结束颜色
    /// - direction: 渐变方向
    init(startColor:UIColor, endColor:UIColor,locations:[NSNumber]? = nil,direction:PHGradientDirection = .leftToRight) {
        super.init(frame: .zero)
        self.layer.addSublayer(gradientLayer)
        gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
        gradientLayer.locations = locations
        reloadDirection()
    }

4.设置渐变方向

根据当前的方向枚举值来,通过修改startPoint和endPoint两个值来修改渐变方向:

    private func reloadDirection() {
        switch direction {
        case .leftToRight:
            gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
            gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)
        case .topToBottom:
            gradientLayer.startPoint = CGPoint(x: 0.5, y: 0)
            gradientLayer.endPoint = CGPoint(x: 0.5, y: 1)
        case .topLeftToBottomRight:
            gradientLayer.startPoint = CGPoint(x: 0, y: 0)
            gradientLayer.endPoint = CGPoint(x: 1, y: 1)
        case .topRightToBottomLeft:
            gradientLayer.startPoint = CGPoint(x: 1, y: 0)
            gradientLayer.endPoint = CGPoint(x: 0, y: 1)
        }
    }

5.添加一些渐变属性

为视图添加一些属性,可以更灵活的修改渐变图层相对应的属性,比如颜色数组,起始和结束位置等等:

    /// 设置颜色
    var colors:[UIColor]? {
        didSet {
            guard let colors = colors else {
                return
            }
            gradientLayer.colors = colors.map({$0.cgColor})
        }
    }
    
    /// 设置locations
    var locations:[NSNumber]? {
        didSet {
            gradientLayer.locations = locations
        }
    }
    
    /// 设置渐变方向
    var direction:PHGradientDirection = .leftToRight {
        didSet {
            reloadDirection()
        }
    }
    
    /// 修改开始点
    var startPoint:CGPoint = CGPoint(x: 0, y: 0.5) {
        didSet {
            gradientLayer.startPoint = startPoint
        }
    }
    
    /// 修改结束点
    var endPoint:CGPoint = CGPoint(x: 1, y: 0.5) {
        didSet {
            gradientLayer.endPoint = endPoint
        }
    }

使用自定义渐变视图

接下来我们就可以和使用UIView一样来使用渐变视图了,我们可以使用任何布局方式,设置视图的任何属性,比如设置圆角。

        let gradientView1 = PHGradientView(startColor: .yellow, endColor:.cyan)
        gradientView1.layer.masksToBounds = true
        gradientView1.layer.cornerRadius = 10.0
        self.view.addSubview(gradientView1)
        gradientView1.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.height.equalTo(100.0)
        }
        let gradientView2 = PHGradientView(startColor: .red, endColor:.blue)
        gradientView2.direction = .topLeftToBottomRight
        gradientView2.layer.masksToBounds = true
        gradientView2.layer.cornerRadius = 10.0
        self.view.addSubview(gradientView2)
        gradientView2.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.top.equalTo(gradientView1.snp.bottom).offset(20.0)
            make.width.height.equalTo(100.0)
        }
        
        let gradientView3 = PHGradientView(startColor: .green, endColor:.purple)
        gradientView3.direction = .topRightToBottomLeft
        gradientView3.layer.masksToBounds = true
        gradientView3.layer.cornerRadius = 10.0
        self.view.addSubview(gradientView3)
        gradientView3.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.top.equalTo(gradientView2.snp.bottom).offset(20.0)
            make.width.height.equalTo(100.0)
        }

效果如下:

结语

通过本文的介绍,我们了解了如何使用 CAGradientLayer 来创建渐变视图,渐变效果不仅能为应用界面增色不少,还能提升用户的视觉体验。在实际开发中,CAGradientLayer 提供了丰富的功能,通过合理配置,可以实现各种各样的渐变效果。

虽然我们在本文中主要讨论了线性渐变,但 CAGradientLayer 还支持径向渐变和圆锥渐变,开发者可以根据需要进行探索和尝试。创建自定义的渐变视图组件,不仅可以简化代码,还能提高项目的可维护性和扩展性。

  • 25
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值