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

All*_*ang 282 uiview uicolor ios

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

Ars*_*Ali 671

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];
Run Code Online (Sandbox Code Playgroud)

迅速:

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)
Run Code Online (Sandbox Code Playgroud)

信息:使用的startPoint和端点改变梯度的方向.

如果有添加到该任何其它视图UIView(如UILabel),可能要考虑设置的那些的背景色UIView的,以[UIColor clearColor]这样的梯度的视图被呈现,而不是背景颜色子视图.使用clearColor具有轻微的性能损失.

  • 不要忘记使用'startPoint'和'endPoint'来改变渐变方向.默认值为(0.5,0)和(0.5,1) - 从上到下方向. (46认同)
  • +1表示所有解决方案中最短的代码量.我刚刚添加到我现有的视图控制器,将2 refs更改为`view`为`self.view`,它就像一个魅力:) (13认同)
  • 这对我帮助很大!在其他地方错过了CGColor部分!谢谢 (13认同)
  • 当我的UIView使用AutoLayout时,我还必须在`viewDidAppear()`和`didRotateFromInterfaceOrientation()`中调用`gradient.frame = view.bounds`,否则渐变的大小不合适. (12认同)
  • 同样相关的是添加此代码的位置.我需要以下帖子才能使其工作:http://stackoverflow.com/a/20059268/1480518 (4认同)

Yuc*_*ong 49

您可以创建自定义类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]
    }
}
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

这在以下方面更好:

  • 无需设置框架 CLayer
  • NSConstraint像往常一样使用UIView
  • 不需要创建子层(更少的内存使用)


Jay*_*kar 35

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

目标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];
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

更新: - Swift3 +

代码: -

 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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

  gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
  gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

有关更多详细信息,请参阅CAGradientLayer Doc

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


Sam*_*her 34

这是我推荐的方法.

为了促进可重用性,我想说创建的一个类别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
Run Code Online (Sandbox Code Playgroud)

然后在实现文件中,指定与此语法每个梯度:

+ (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;
}
Run Code Online (Sandbox Code Playgroud)

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

CAGradientLayer *backgroundLayer = [CAGradientLayer purpleGradientLayer];
backgroundLayer.frame = self.view.frame;
[self.view.layer insertSublayer:backgroundLayer atIndex:0];
Run Code Online (Sandbox Code Playgroud)

  • viewDidLoad可以工作,您只需要使用[backgroundLayer setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]设置AutoResizingMask; (2认同)

bla*_*ahn 20

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

DDGradientView.h:

#import <UIKit/UIKit.h>

@interface DDGradientView : UIView {

}
@end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


Har*_*ris 16

extension UIView {

    func applyGradient(isVertical: Bool, colorArray: [UIColor]) { 
        layer.sublayers?.filter({ $0 is CAGradientLayer }).forEach({ $0.removeFromSuperlayer() })
         
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = colorArray.map({ $0.cgColor })
        if isVertical {
            //top to bottom
            gradientLayer.locations = [0.0, 1.0]
        } else {
            //left to right
            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)
    }

}
Run Code Online (Sandbox Code Playgroud)

用法

someView.applyGradient(isVertical: true, colorArray: [.green, .blue])
Run Code Online (Sandbox Code Playgroud)


小智 12

快速实施:

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)
Run Code Online (Sandbox Code Playgroud)


pat*_*ckS 10

我已经在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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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

myImageView.addGradientWithColor(UIColor.blue)
Run Code Online (Sandbox Code Playgroud)


flo*_*bit 9

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

哦,如果你使用的是故事板像我这样做,请确保调用gradientBackground(from:to:direction:)viewDidLayoutSubviews()或更高版本.

斯威夫特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)
    }
}
Run Code Online (Sandbox Code Playgroud)


Tom*_* C. 8

一种快速的方法

这个答案建立在上面的答案的基础上,并提供了处理在旋转期间没有正确应用的梯度问题的实现.它通过将渐变层更改为正方形来满足此问题,以便在所有方向上的旋转产生正确的渐变.函数签名包含一个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)
    }
Run Code Online (Sandbox Code Playgroud)

使用:

在viewDidLoad中......

  override func viewDidLoad() {
        super.viewDidLoad()
        configureGradientBackground(UIColor.redColor().CGColor, UIColor.whiteColor().CGColor)
  }
Run Code Online (Sandbox Code Playgroud)

扩展实施

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)
    }

}
Run Code Online (Sandbox Code Playgroud)

扩展用例示例:

 override func viewDidLoad() {
        super.viewDidLoad()

        self.view.layer.configureGradientBackground(UIColor.purpleColor().CGColor, UIColor.blueColor().CGColor, UIColor.whiteColor().CGColor)
 }
Run Code Online (Sandbox Code Playgroud)

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

斯威夫特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)
    }    
}
Run Code Online (Sandbox Code Playgroud)

扩展用例示例:

override func viewDidLoad() {
    super.viewDidLoad()

    self.view.layer.configureGradientBackground(UIColor.purple.cgColor, UIColor.blue.cgColor, UIColor.white.cgColor)
}
Run Code Online (Sandbox Code Playgroud)


Ken*_*ner 5

你在寻找什么CAGradientLayer.每UIView有一个图层-成层您可以添加子层,就像你可以添加子视图.一种特定类型的是CAGradientLayer,在这里,你给它的颜色之间gradiate数组.

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

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

请注意,您需要包括QuartZCore框架,以访问所有一个UIView的层部分.


Ron*_*ini 5

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

\n\n
viewDidLayoutSubviews\xe2\x80\x8a\n
Run Code Online (Sandbox Code Playgroud)\n\n

正确更新视图

\n


Ale*_*kov 5

斯威夫特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]
    }
}
Run Code Online (Sandbox Code Playgroud)