背景色漸變-邊框色漸變邊框

僅供參考

//MARK: -擴(kuò)展背景色漸變功能
extension UIView {
    /// 漸變方向枚舉
    enum GradientDirection {
        case leftToRight        // 從左到右
        case topToBottom        // 從上到下
        case leftTopToRightBottom // 左上到右下
        case rightTopToLeftBottom // 右上到左下
        case custom(start: CGPoint, end: CGPoint) // 自定義方向
        
        /// 計算屬性:返回對應(yīng)方向的起止點
        var points: (start: CGPoint, end: CGPoint) {
            switch self {
            case .leftToRight:
                return (CGPoint(x: 0, y: 0.5), CGPoint(x: 1, y: 0.5))
            case .topToBottom:
                return (CGPoint(x: 0.5, y: 0), CGPoint(x: 0.5, y: 1))
            case .leftTopToRightBottom:
                return (CGPoint(x: 0, y: 0), CGPoint(x: 1, y: 1))
            case .rightTopToLeftBottom:
                return (CGPoint(x: 1, y: 0), CGPoint(x: 0, y: 1))
            case .custom(let start, let end):
                return (start, end)
            }
        }
    }
    
    /// 設(shè)置漸變背景色
    /// - Parameters:
    ///   - colors: 漸變顏色數(shù)組
    ///   - direction: 漸變方向,默認(rèn)從左到右
    ///   - locations: 顏色位置數(shù)組,可選
    func addGradientBackground(colors: [UIColor],
                               direction: GradientDirection = .leftToRight,
                               locations: [NSNumber]? = nil) {
        // 移除已有的漸變層
        removeGradientBackground()
        
        // 創(chuàng)建漸變層
        let gradientLayer = CAGradientLayer()
        gradientLayer.name = "GradientBackground" // 設(shè)置標(biāo)識名稱
        gradientLayer.frame = bounds
        gradientLayer.colors = colors.map { $0.cgColor }
        
        // 設(shè)置漸變方向
        let (startPoint, endPoint) = direction.points
        gradientLayer.startPoint = startPoint
        gradientLayer.endPoint = endPoint
        
        // 設(shè)置顏色位置
        if let locations = locations {
            gradientLayer.locations = locations
        }
        
        // 將漸變層插入到最底層
        layer.insertSublayer(gradientLayer, at: 0)
    }
    
    /// 更新漸變背景層的大小
    func updateGradientBackground() {
        guard let gradientLayer = layer.sublayers?
            .first(where: { $0.name == "GradientBackground" }) as? CAGradientLayer else {
            return
        }
        gradientLayer.frame = bounds
    }
    
    /// 移除漸變背景層
    func removeGradientBackground() {
        layer.sublayers?
            .filter { $0.name == "GradientBackground" }
            .forEach { $0.removeFromSuperlayer() }
    }
}

//MARK: -漸變邊框擴(kuò)展實現(xiàn)
extension UIView {

    /// 給 UIView 添加漸變邊框
    /// - Parameters:
    ///   - colors: 漸變顏色數(shù)組(至少需要2種顏色)
    ///   - direction: 漸變方向,默認(rèn)為從左到右
    ///   - lineWidth: 邊框?qū)挾?,默認(rèn) 1
    ///   - cornerRadius: 圓角半徑,默認(rèn)為視圖當(dāng)前的 `cornerRadius`
    func addGradientBorder(colors: [UIColor],
                           direction: GradientDirection = .leftToRight,
                           lineWidth: CGFloat = 1,
                           cornerRadius: CGFloat? = nil) {
        guard colors.count > 1 else { return } // 至少需要 2 種顏色

        // 移除舊的漸變邊框,防止重復(fù)添加
        removeGradientBorder()

        let gradientLayer = CAGradientLayer()
        gradientLayer.name = "GradientBorderLayer"
        gradientLayer.colors = colors.map { $0.cgColor }
        let (startPoint, endPoint) = direction.points
        gradientLayer.startPoint = startPoint
        gradientLayer.endPoint = endPoint
        gradientLayer.frame = bounds // 設(shè)置初始大小

        // 創(chuàng)建形狀層(用于定義邊框路徑)
        let shapeLayer = CAShapeLayer()
        shapeLayer.lineWidth = lineWidth
        shapeLayer.fillColor = nil
        shapeLayer.strokeColor = UIColor.black.cgColor
        shapeLayer.lineCap = .round

        // 設(shè)置圓角(優(yōu)先使用參數(shù)值,否則使用視圖當(dāng)前的圓角)
        let effectiveCornerRadius = cornerRadius ?? layer.cornerRadius
        shapeLayer.path = UIBezierPath(
            roundedRect: bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2),
            cornerRadius: effectiveCornerRadius
        ).cgPath

        // 綁定 mask
        gradientLayer.mask = shapeLayer
        layer.addSublayer(gradientLayer)
    }

    /// 移除漸變邊框
    func removeGradientBorder() {
        layer.sublayers?.removeAll { $0.name == "GradientBorderLayer" }
    }

    /// 更新漸變邊框(在 `layoutSubviews` 里調(diào)用)
    func updateGradientBorder() {
        guard let gradientLayer = layer.sublayers?.first(where: { $0.name == "GradientBorderLayer" }) as? CAGradientLayer,
              let shapeLayer = gradientLayer.mask as? CAShapeLayer else {
            return
        }

        // 更新 `frame`
        gradientLayer.frame = bounds

        // 重新計算邊框路徑
        let lineWidth = shapeLayer.lineWidth
        let cornerRadius = layer.cornerRadius // 使用當(dāng)前的 `cornerRadius`
        shapeLayer.path = UIBezierPath(
            roundedRect: bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2),
            cornerRadius: cornerRadius
        ).cgPath
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容