Swift Control View,Label渐变颜色(源码)

一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络,希望未来技术之巅上有你们也有我。

要用frame约束方式

文章目录

使用

参数说明

参数说明:

colors: 颜色数组

locations:控制颜色过渡的位置

startPoint: 渐变起点

endPoint: 渐变终点

注意:颜色数组有3个颜色,控制颜色过渡的位置数组对应要有3个参数,渐变起点就是颜色于颜色过渡的位置

坐标系说明

bash 复制代码
(0,0) ─────────── (1,0)
  │                  │
  │    UIView        │
  │                  │
(0,1) ─────────── (1,1)

View - 示例代码

bash 复制代码
let box = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 100))
box.az_setGradientBackground(
    colors: [UIColor.red, UIColor.blue],
    locations: [0.0, 1.0],
    startPoint: CGPoint(x: 0, y: 0.5),
    endPoint: CGPoint(x: 1, y: 0.5)
)
view.addSubview(box)
box.center = view.center

效果

Label - 示例代码

bash 复制代码
let label = GradientLabel()
label.frame = CGRect(x: 50, y: 100, width: 300, height: 60)
label.text = "渐变文字效果"
label.font = UIFont.boldSystemFont(ofSize: 30)
label.textAlignment = .center

// 设置渐变(通过关联属性)
label.az_colors = [UIColor.systemPink.cgColor, UIColor.systemPurple.cgColor]
label.az_locations = [0.0, 1.0]
label.az_startPoint = CGPoint(x: 0, y: 0.5)
label.az_endPoint = CGPoint(x: 1, y: 0.5)

view.addSubview(label)
label.center = view.center

效果

封装代码

GradientLabel

bash 复制代码
import UIKit

class GradientLabel: UILabel {

    override class var layerClass: AnyClass {
        return CAGradientLayer.self
    }
}

GradientView

bash 复制代码
import UIKit

class GradientView: UIView {

    override class var layerClass: AnyClass {
        return CAGradientLayer.self
    }
}

UIView+AZGradient

bash 复制代码
import UIKit
import ObjectiveC.runtime

private var azColorsKey: UInt8 = 0
private var azLocationsKey: UInt8 = 0
private var azStartPointKey: UInt8 = 0
private var azEndPointKey: UInt8 = 0

extension UIView {

    // MARK: - Associated Properties

    var az_colors: [CGColor]? {
        get {
            return objc_getAssociatedObject(self, &azColorsKey) as? [CGColor]
        }
        set {
            objc_setAssociatedObject(self, &azColorsKey, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
            if let layer = self.layer as? CAGradientLayer {
                layer.colors = newValue
            }
        }
    }

    var az_locations: [NSNumber]? {
        get {
            return objc_getAssociatedObject(self, &azLocationsKey) as? [NSNumber]
        }
        set {
            objc_setAssociatedObject(self, &azLocationsKey, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
            if let layer = self.layer as? CAGradientLayer {
                layer.locations = newValue
            }
        }
    }

    var az_startPoint: CGPoint {
        get {
            return (objc_getAssociatedObject(self, &azStartPointKey) as? NSValue)?.cgPointValue ?? .zero
        }
        set {
            objc_setAssociatedObject(self, &azStartPointKey, NSValue(cgPoint: newValue), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            if let layer = self.layer as? CAGradientLayer {
                layer.startPoint = newValue
            }
        }
    }

    var az_endPoint: CGPoint {
        get {
            return (objc_getAssociatedObject(self, &azEndPointKey) as? NSValue)?.cgPointValue ?? .zero
        }
        set {
            objc_setAssociatedObject(self, &azEndPointKey, NSValue(cgPoint: newValue), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            if let layer = self.layer as? CAGradientLayer {
                layer.endPoint = newValue
            }
        }
    }

    // MARK: - 创建渐变View
    static func az_gradientView(
        colors: [UIColor]?,
        locations: [NSNumber]?,
        startPoint: CGPoint,
        endPoint: CGPoint
    ) -> UIView {

        let view = GradientView()
        view.az_setGradientBackground(colors: colors,
                                      locations: locations,
                                      startPoint: startPoint,
                                      endPoint: endPoint)
        return view
    }

    // MARK: - 设置渐变
    func az_setGradientBackground(
        colors: [UIColor]?,
        locations: [NSNumber]?,
        startPoint: CGPoint,
        endPoint: CGPoint
    ) {

        guard let colors = colors else { return }

        let gradient = CAGradientLayer()
        gradient.colors = colors.map { $0.cgColor }
        gradient.locations = locations
        gradient.startPoint = startPoint
        gradient.endPoint = endPoint
        gradient.frame = self.bounds
        
        gradient.cornerRadius = self.layer.cornerRadius

        self.layer.insertSublayer(gradient, at: 0)
    }
}
相关推荐
雪落漂泊2 分钟前
C++算法 二分查找篇(上)
开发语言·c++·算法
传奇开心果编程38 分钟前
【Flutter踩坑排雷】第19课:路由硬编码坑|字符串路由书写错误,页面跳转失败排查
android·flutter·ios·移动开发·跨平台·ui框架·声明式ui
波力海苔夹心脆6751 小时前
C# WPF 资源字典详解:ResourceDictionary、MergedDictionaries 与自定义控件案例
开发语言·c#·wpf·入门教程·resource·资源字典
不会算法的笨小孩1 小时前
异常的使用以及会出现的问题
开发语言·c++·c++11·异常
茶底世界之下4 小时前
雨后街口的斑马线:用 Awaking 把颜色让给光与步伐
ios·app·产品
Hhy_11074 小时前
《C++深度解构06》手撕 string —— 从底层内存管理到深浅拷贝彻底吃透
c语言·开发语言·c++·学习·visual studio
starzy19904 小时前
深入理解Scala函数定义:从方法到函数的类型跨越
开发语言·scala
starzy19904 小时前
深入理解Scala递归函数:从栈溢出到尾调用优化
开发语言·scala
三*一4 小时前
Mapbox‑GL JS 多边形折点编辑工具:实现原理、功能拆解与踩坑总结
开发语言·javascript·ecmascript
YSL0701244 小时前
C++基础
开发语言·c++