首页 文章

以编程方式创建具有颜色渐变的UIView

提问于
浏览
243

我正在尝试在运行时生成具有渐变颜色背景(纯色到透明)的视图 . 有没有办法做到这一点?

19 回答

  • 619

    您可以创建自定义类 GradientView

    Swift 4, Swift 3

    class GradientView: UIView {
        override open class var layerClass: AnyClass {
           return CAGradientLayer.classForCoder()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            let gradientLayer = layer as! CAGradientLayer
            gradientLayer.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
        }
    }
    

    在故事板中,将类类型设置为您想要具有渐变背景的任何视图:

    这在以下方面更好:

    • 无需设置 CLayer 的框架

    • UIView 上照常使用 NSConstraint

    • 不需要创建子图层(减少内存使用)

  • 35

    我在swift中实现了这个扩展:

    Swift 3

    extension UIView {
        func addGradientWithColor(color: UIColor) {
            let gradient = CAGradientLayer()
            gradient.frame = self.bounds
            gradient.colors = [UIColor.clear.cgColor, color.cgColor]
    
            self.layer.insertSublayer(gradient, at: 0)
        }
    }
    

    Swift 2.2

    extension UIView {
        func addGradientWithColor(color: UIColor) {
            let gradient = CAGradientLayer()
            gradient.frame = self.bounds
            gradient.colors = [UIColor.clearColor().CGColor, color.CGColor]
    
            self.layer.insertSublayer(gradient, atIndex: 0)
        }
    }
    

    不,我可以像这样在每个视图上设置渐变:

    myImageView.addGradientWithColor(UIColor.blue)
    
  • 3

    Objective-C:

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
    CAGradientLayer *gradient = [CAGradientLayer layer];
    
    gradient.frame = view.bounds;
    gradient.colors = @[(id)[UIColor whiteColor].CGColor, (id)[UIColor blackColor].CGColor];
    
    [view.layer insertSublayer:gradient atIndex:0];
    

    斯威夫特:

    let view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 50))
    let gradient = CAGradientLayer()
    
    gradient.frame = view.bounds
    gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
    
    view.layer.insertSublayer(gradient, at: 0)
    

    Info :使用startPoint和endPoint到change direction of gradient .

    如果在此 UIView 上添加了任何其他视图(例如 UILabel ),您可能需要考虑将 UIView 的背景颜色设置为 [UIColor clearColor] ,以便显示渐变视图而不是子视图的背景颜色 . 使用 clearColor 会有轻微的性能影响 .

  • 20

    调用上面的解决方案来更新层是一个好主意

    viewDidLayoutSubviews 
    

    正确更新视图

  • 0

    A Swift Approach

    这个答案 Build 在上面的答案的基础上,并提供了处理旋转期间未正确应用的梯度问题的实现 . 它通过将渐变层更改为正方形来满足此问题,以便在所有方向上的旋转产生正确的渐变 . 函数签名包含一个Swift可变参数,允许根据需要传入尽可能多的CGColorRef(CGColor)(参见示例用法) . 还提供了作为Swift扩展的示例,以便可以将渐变应用于任何UIView .

    func configureGradientBackground(colors:CGColorRef...){
    
            let gradient: CAGradientLayer = CAGradientLayer()
            let maxWidth = max(self.view.bounds.size.height,self.view.bounds.size.width)
            let squareFrame = CGRect(origin: self.view.bounds.origin, size: CGSizeMake(maxWidth, maxWidth))
            gradient.frame = squareFrame
    
            gradient.colors = colors
            view.layer.insertSublayer(gradient, atIndex: 0)
        }
    

    To use:

    在viewDidLoad中......

    override func viewDidLoad() {
            super.viewDidLoad()
            configureGradientBackground(UIColor.redColor().CGColor, UIColor.whiteColor().CGColor)
      }
    

    Extension implementation

    extension CALayer {
    
    
        func configureGradientBackground(colors:CGColorRef...){
    
            let gradient = CAGradientLayer()
    
            let maxWidth = max(self.bounds.size.height,self.bounds.size.width)
            let squareFrame = CGRect(origin: self.bounds.origin, size: CGSizeMake(maxWidth, maxWidth))
            gradient.frame = squareFrame
    
            gradient.colors = colors
    
            self.insertSublayer(gradient, atIndex: 0)
        }
    
    }
    

    扩展用例示例:

    override func viewDidLoad() {
            super.viewDidLoad()
    
            self.view.layer.configureGradientBackground(UIColor.purpleColor().CGColor, UIColor.blueColor().CGColor, UIColor.whiteColor().CGColor)
     }
    

    这意味着渐变背景现在可以应用于任何UIControl,因为所有控件都是UIViews(或子类),并且所有UIView都有CALayers .

    Swift 4

    扩展实施

    extension CALayer {
        public func configureGradientBackground(_ colors:CGColor...){
    
            let gradient = CAGradientLayer()
    
            let maxWidth = max(self.bounds.size.height,self.bounds.size.width)
            let squareFrame = CGRect(origin: self.bounds.origin, size: CGSize(width: maxWidth, height: maxWidth))
            gradient.frame = squareFrame
    
            gradient.colors = colors
    
            self.insertSublayer(gradient, at: 0)
        }    
    }
    

    扩展用例示例:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.view.layer.configureGradientBackground(UIColor.purple.cgColor, UIColor.blue.cgColor, UIColor.white.cgColor)
    }
    
  • 1

    SWIFT 3

    To add a gradient layer on your view

    • 绑定您的视图插座
    @IBOutlet var YOURVIEW : UIView!
    
    • 定义CAGradientLayer()
    var gradient = CAGradientLayer()
    
    • 以下是您必须在viewDidLoad中编写的代码

    YOURVIEW.layoutIfNeeded()

    gradient.startPoint = CGPoint(x: CGFloat(0), y: CGFloat(1)) gradient.endPoint = CGPoint(x: CGFloat(1), y: CGFloat(0)) gradient.frame = YOURVIEW.bounds gradient.colors = [UIColor.red.cgColor, UIColor.green.cgColor] gradient.colors = [ UIColor(red: 255.0/255.0, green: 56.0/255.0, blue: 224.0/255.0, alpha: 1.0).cgColor,UIColor(red: 86.0/255.0, green: 13.0/255.0, blue: 232.0/255.0, alpha: 1.0).cgColor,UIColor(red: 16.0/255.0, green: 173.0/255.0, blue: 245.0/255.0, alpha: 1.0).cgColor] gradient.locations = [0.0 ,0.6 ,1.0] YOURVIEW.layer.insertSublayer(gradient, at: 0)

  • 3

    你在找什么是 CAGradientLayer . 每个 UIView 都有一个图层 - 您可以在该图层中添加子图层,就像添加子视图一样 . 一个特定的类型是 CAGradientLayer ,您可以在其中为它们提供一系列颜色以进行渐变 .

    一个例子是这个简单的渐变视图包装器:

    http://oleb.net/blog/2010/04/obgradientview-a-simple-uiview-wrapper-for-cagradientlayer/

    请注意,您需要包含QuartZCore框架才能访问UIView的所有图层部分 .

  • 3

    由于我在整个应用程序中只需要一种渐变,因此我创建了一个UIView的子类,并在初始化时使用固定颜色预先配置了渐变层 . UIView的初始化程序调用configureGradientLayer-method,它配置CAGradientLayer:

    DDGradientView.h:

    #import <UIKit/UIKit.h>
    
    @interface DDGradientView : UIView {
    
    }
    @end
    

    DDGradientView.m:

    #import "DDGradientView.h"
    
    @implementation DDGradientView
    
    // Change the views layer class to CAGradientLayer class
    + (Class)layerClass
    {
        return [CAGradientLayer class];
    }
    
    - (instancetype)initWithCoder:(NSCoder *)aDecoder {
        self = [super initWithCoder:aDecoder];
        if(self) {
            [self configureGradientLayer];
        }
        return self;
    }
    
    - (instancetype)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if(self) {
            [self configureGradientLayer];
        }
        return self;
    }
    
    // Make custom configuration of your gradient here   
    - (void)configureGradientLayer {
        CAGradientLayer *gLayer = (CAGradientLayer *)self.layer;
        gLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor], (id)[[UIColor lightGrayColor] CGColor], nil];
    }
    @end
    
  • 34

    我使用Swift的扩展功能和枚举扩展了接受的答案 .

    哦,如果你像我一样使用Storyboard,请务必在 viewDidLayoutSubviews() 或之后调用 gradientBackground(from:to:direction:) .

    Swift 3

    enum GradientDirection {
        case leftToRight
        case rightToLeft
        case topToBottom
        case bottomToTop
    }
    
    extension UIView {
        func gradientBackground(from color1: UIColor, to color2: UIColor, direction: GradientDirection) {
            let gradient = CAGradientLayer()
            gradient.frame = self.bounds
            gradient.colors = [color1.cgColor, color2.cgColor]
    
            switch direction {
            case .leftToRight:
                gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
                gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
            case .rightToLeft:
                gradient.startPoint = CGPoint(x: 1.0, y: 0.5)
                gradient.endPoint = CGPoint(x: 0.0, y: 0.5)
            case .bottomToTop:
                gradient.startPoint = CGPoint(x: 0.5, y: 1.0)
                gradient.endPoint = CGPoint(x: 0.5, y: 0.0)
            default:
                break
            }
    
            self.layer.insertSublayer(gradient, at: 0)
        }
    }
    
  • 3

    在Swift 3.1中,我已将此扩展添加到UIView

    import Foundation
    import UIKit
    import CoreGraphics
    
    
    extension UIView {
        func gradientOfView(withColours: UIColor...) {
    
            var cgColours = [CGColor]()
    
            for colour in withColours {
                cgColours.append(colour.cgColor)
            }
            let grad = CAGradientLayer()
            grad.frame = self.bounds
            grad.colors = cgColours
            self.layer.insertSublayer(grad, at: 0)
        }
    }
    

    然后我打电话给他

    class OverviewVC: UIViewController {
    
            override func viewDidLoad() {
                super.viewDidLoad()
    
                self.view.gradientOfView(withColours: UIColor.red,UIColor.green, UIColor.blue)
    
            }
    }
    
  • 0

    Swift 4:

    在IB中正确显示渐变:

    @IBDesignable public class GradientView: UIView {
    
        override open class var layerClass: AnyClass {
            return CAGradientLayer.classForCoder()
        }
    
        required public init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            configureGradientLayer()
        }
    
        public override init(frame: CGRect) {
            super.init(frame: frame)
            configureGradientLayer()
        }
    
        func configureGradientLayer() {
            let gradientLayer = layer as! CAGradientLayer
            gradientLayer.colors = [UIColor(hex: 0x003399).cgColor, UIColor(hex: 0x00297b).cgColor]
        }
    }
    
  • 8

    To give gradient color to UIView (swift 4.2)

    func makeGradientLayer(`for` object : UIView, startPoint : CGPoint, endPoint : CGPoint, gradientColors : [Any]) -> CAGradientLayer {
            let gradient: CAGradientLayer = CAGradientLayer()
            gradient.colors = gradientColors
            gradient.locations = [0.0 , 1.0]
            gradient.startPoint = startPoint
            gradient.endPoint = endPoint
            gradient.frame = CGRect(x: 0, y: 0, w: object.frame.size.width, h: object.frame.size.height)
            return gradient
        }
    

    How to use

    let start : CGPoint = CGPoint(x: 0.0, y: 1.0)
    let end : CGPoint = CGPoint(x: 1.0, y: 1.0)
    
    let gradient: CAGradientLayer = makeGradientLayer(for: cell, startPoint: start, endPoint: end, gradientColors: [
                        UIColor(red:0.92, green:0.07, blue:0.4, alpha:1).cgColor,
                        UIColor(red:0.93, green:0.11, blue:0.14, alpha:1).cgColor
                        ])
    
    self.vwTemp.layer.insertSublayer(gradient, at: 0)
    
  • 12

    尝试这对我来说就像一个魅力,

    Objective C

    我已将 RGB 渐变背景颜色设置为 UIview

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,35)];
       CAGradientLayer *gradient = [CAGradientLayer layer];
       gradient.frame = view.bounds;
       gradient.startPoint = CGPointZero;
       gradient.endPoint = CGPointMake(1, 1);
       gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:34.0/255.0 green:211/255.0 blue:198/255.0 alpha:1.0] CGColor],(id)[[UIColor colorWithRed:145/255.0 green:72.0/255.0 blue:203/255.0 alpha:1.0] CGColor], nil];
       [view.layer addSublayer:gradient];
    

    UPDATED :- Swift3 +

    Code : -

    var gradientView = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 35))
     let gradientLayer:CAGradientLayer = CAGradientLayer()
     gradientLayer.frame.size = self.gradientView.frame.size
     gradientLayer.colors = 
     [UIColor.white.cgColor,UIColor.red.withAlphaComponent(1).cgColor] 
    //Use diffrent colors
     gradientView.layer.addSublayer(gradientLayer)
    

    您可以添加渐变颜色的起点和终点 .

    gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
      gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
    

    有关详细说明,请参阅CAGradientLayer Doc

    希望这对某些人有所帮助 .

  • 27

    我的解决方案是创建 UIView 子类,其中 CAGradientLayer 可作为只读属性访问 . 这样您就可以根据需要自定义渐变,而不需要自己处理布局更改 . 子类实现:

    @interface GradientView : UIView
    
    @property (nonatomic, readonly) CAGradientLayer *gradientLayer;
    
    @end
    
    @implementation GradientView
    
    + (Class)layerClass
    {
        return [CAGradientLayer class];
    }
    
    - (CAGradientLayer *)gradientLayer
    {
        return (CAGradientLayer *)self.layer;
    }
    
    @end
    

    用法:

    self.iconBackground = [GradientView new];
    [self.background addSubview:self.iconBackground];
    self.iconBackground.gradientLayer.colors = @[(id)[UIColor blackColor].CGColor, (id)[UIColor whiteColor].CGColor];
    self.iconBackground.gradientLayer.startPoint = CGPointMake(1.0f, 1.0f);
    self.iconBackground.gradientLayer.endPoint = CGPointMake(0.0f, 0.0f);
    
  • 0

    这是我推荐的方法 .

    为了提高可重用性,我想创建一个 CAGradientLayer 的类别,并将所需的渐变添加为类方法 . 在 header 文件中指定它们,如下所示:

    #import <QuartzCore/QuartzCore.h>
    
    @interface CAGradientLayer (SJSGradients)
    
    + (CAGradientLayer *)redGradientLayer;
    + (CAGradientLayer *)blueGradientLayer;
    + (CAGradientLayer *)turquoiseGradientLayer;
    + (CAGradientLayer *)flavescentGradientLayer;
    + (CAGradientLayer *)whiteGradientLayer;
    + (CAGradientLayer *)chocolateGradientLayer;
    + (CAGradientLayer *)tangerineGradientLayer;
    + (CAGradientLayer *)pastelBlueGradientLayer;
    + (CAGradientLayer *)yellowGradientLayer;
    + (CAGradientLayer *)purpleGradientLayer;
    + (CAGradientLayer *)greenGradientLayer;
    
    @end
    

    然后在您的实现文件中,使用以下语法指定每个渐变:

    + (CAGradientLayer *)flavescentGradientLayer
    {
        UIColor *topColor = [UIColor colorWithRed:1 green:0.92 blue:0.56 alpha:1];
        UIColor *bottomColor = [UIColor colorWithRed:0.18 green:0.18 blue:0.18 alpha:1];
    
        NSArray *gradientColors = [NSArray arrayWithObjects:(id)topColor.CGColor, (id)bottomColor.CGColor, nil];
        NSArray *gradientLocations = [NSArray arrayWithObjects:[NSNumber numberWithInt:0.0],[NSNumber numberWithInt:1.0], nil];
    
        CAGradientLayer *gradientLayer = [CAGradientLayer layer];
        gradientLayer.colors = gradientColors;
        gradientLayer.locations = gradientLocations;
    
        return gradientLayer;
    }
    

    然后只需在 ViewController 或任何其他所需的 subclass 中导入此类别,并像这样使用它:

    CAGradientLayer *backgroundLayer = [CAGradientLayer purpleGradientLayer];
    backgroundLayer.frame = self.view.frame;
    [self.view.layer insertSublayer:backgroundLayer atIndex:0];
    
  • 8
    extension UIView {
    
        func applyGradient(isTopBottom: Bool, colorArray: [UIColor]) {
            if let sublayers = layer.sublayers {
                let _ = sublayers.filter({ $0 is CAGradientLayer }).map({ $0.removeFromSuperlayer() })
            }
    
            let gradientLayer = CAGradientLayer()
            gradientLayer.colors = colorArray.map({ $0.cgColor })
            if isTopBottom {
                gradientLayer.locations = [0.0, 1.0]
            } else {
                //leftRight
                gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
                gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
            }
    
            backgroundColor = .clear
            gradientLayer.frame = bounds
            layer.insertSublayer(gradientLayer, at: 0)
        }
    
    }
    

    用法

    someView.applyGradient(isTopBottom: true, colorArray: [.green, .blue])
    
  • 5

    我在我的代码中实现了这一点 .

    UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 31.0f)];
    view1.backgroundColor = [UIColor clearColor];
    CAGradientLayer *gradient = [CAGradientLayer layer];
    gradient.frame = view1.bounds;
    UIColor *topColor = [UIColor colorWithRed:132.0/255.0 green:222.0/255.0 blue:109.0/255.0 alpha:1.0];
    UIColor *bottomColor = [UIColor colorWithRed:31.0/255.0 green:150.0/255.0 blue:99.0/255.0 alpha:1.0];
    gradient.colors = [NSArray arrayWithObjects:(id)[topColor CGColor], (id)[bottomColor CGColor], nil];
    
    
    [view1.layer insertSublayer:gradient atIndex:0];
    

    现在我可以在视图上看到渐变 .

  • 6

    Swift Implementation:

    var gradientLayerView: UIView = UIView(frame: CGRectMake(0, 0, view.bounds.width, 50))
    var gradient: CAGradientLayer = CAGradientLayer()
    gradient.frame = gradientLayerView.bounds
    gradient.colors = [UIColor.grayColor().CGColor, UIColor.clearColor().CGColor]
    gradientLayerView.layer.insertSublayer(gradient, atIndex: 0)
    self.view.layer.insertSublayer(gradientLayerView.layer, atIndex: 0)
    
  • 2

    基于雨辰版本的简单快速视图

    class GradientView: UIView {
        override class func layerClass() -> AnyClass { return CAGradientLayer.self }
    
        lazy var gradientLayer: CAGradientLayer = {
            return self.layer as! CAGradientLayer
        }()
    
        override init(frame: CGRect) {
            super.init(frame: frame)
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    
    }
    

    那么你可以像这样初始化后使用gradientLayer ...

    someView.gradientLayer.colors = [UIColor.whiteColor().CGColor, UIColor.blackColor().CGColor]
    

相关问题