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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23074539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:57:25  来源:igfitidea点击:

Programmatically create a UIView with color gradient

iosuiviewuicolor

提问by Allan Jiang

I'm trying to generate a view with a gradient color background (A solid color to transparent) at runtime. Is there a way of doing that?

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

回答by Arslan Ali

Objective-C:

目标-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];

Swift:

迅速:

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: use startPoint and endPoint to change direction of gradient.

信息使用 startPoint 和 endPoint 来改变渐变的方向

If there are any other views added onto this UIView(such as a UILabel), you may want to consider setting the background color of those UIView's to [UIColor clearColor]so the gradient view is presented instead of the background color for sub views. Using clearColorhas a slight performance hit.

如果添加了任何其他视图UIView(例如 a UILabel),您可能需要考虑将那些UIView's的背景颜色设置[UIColor clearColor]为渐变视图,而不是子视图的背景颜色。使用clearColor对性能有轻微影响。

回答by Yuchen Zhong

You can create a custom class GradientView:

您可以创建自定义类GradientView

Swift 5

斯威夫特 5

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

In the storyboard, set the class type to any view that you want to have gradient background:

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

enter image description here

在此处输入图片说明

This is better in the following ways:

这在以下方面更好:

  • No need to set frame of CLayer
  • Use NSConstraintas usual on the UIView
  • Don't need to create sublayers (less memory use)
  • 无需设置框架 CLayer
  • NSConstraint像往常一样使用UIView
  • 不需要创建子层(更少的内存使用)

回答by Jaywant Khedkar

Try This it worked like a charm for me,

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

Objective C

目标 C

I have set RGBgradient background Color to UIview

我已将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];

enter image description here

在此处输入图片说明

UPDATED :-Swift3 +

更新:- 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)

enter image description here

在此处输入图片说明

You can add starting and end point of gradient color.

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

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

enter image description here

在此处输入图片说明

For more details description refer CAGradientLayer Doc

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

Hope this is help for some one .

希望这对某人有所帮助。

回答by Sam Fischer

This is my recommended approach.

这是我推荐的方法。

To promote reusability, I'd say create a category of CAGradientLayerand add your desired gradients as class methods. Specify them in the headerfile like this :

为了提高可重用性,我会说创建一个类别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

Then in your implementation file, specify each gradient with this syntax :

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

+ (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;
}

Then simply import this category in your ViewControlleror any other required subclass, and use it like this :

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

CAGradientLayer *backgroundLayer = [CAGradientLayer purpleGradientLayer];
backgroundLayer.frame = self.view.frame;
[self.view.layer insertSublayer:backgroundLayer atIndex:0];

回答by blauzahn

Since I only needed one type of gradient throughout my app I created a subclass of UIView and preconfigured the gradient layer on initialization with fixed colors. The initializers of UIView call the configureGradientLayer-method, which configures the CAGradientLayer:

由于我在整个应用程序中只需要一种类型的渐变,因此我创建了 UIView 的子类,并在初始化时使用固定颜色预配置渐变层。UIView 的初始值设定项调用configureGradientLayer方法,该方法配置 CAGradientLayer:

DDGradientView.h:

DDGradientView.h:

#import <UIKit/UIKit.h>

@interface DDGradientView : UIView {

}
@end

DDGradientView.m:

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

回答by Siva Visakan

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)

回答by flocbit

I've extended the accepted answer a little using Swift's extension functionality as well as an enum.

我已经使用 Swift 的扩展功能以及枚举稍微扩展了已接受的答案。

Oh and if you are using Storyboard like I do, make sure to call gradientBackground(from:to:direction:)in viewDidLayoutSubviews()or later.

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

Swift 3

斯威夫特 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)
    }
}

回答by patrickS

I have implemented this in swift with an extension:

我已经通过扩展快速实现了这一点:

Swift 3

斯威夫特 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

斯威夫特 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)
    }
}

No I can set a gradient on every view like this:

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

myImageView.addGradientWithColor(UIColor.blue)

回答by Tommie C.

A Swift Approach

快速的方法

This answer builds on the answers above and provides implementation for dealing with the problem of the gradient not being properly applied during rotation. It satisfies this problem by changing the gradient layer to a square so that rotation in all directions results in a correct gradient. The function signature includes a Swift variadic argument that allows one to pass in as many CGColorRef's (CGColor) as needed (see sample usage). Also provided is an example as a Swift extension so that one can apply a gradient to any UIView.

这个答案建立在上述答案的基础上,并提供了处理旋转过程中没有正确应用梯度的问题的实现。它通过将梯度层更改为正方形来满足此问题,以便在所有方向上旋转都会产生正确的梯度。函数签名包括一个 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:

使用:

in viewDidLoad...

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

}

Extension use-case example:

扩展用例示例:

 override func viewDidLoad() {
        super.viewDidLoad()

        self.view.layer.configureGradientBackground(UIColor.purpleColor().CGColor, UIColor.blueColor().CGColor, UIColor.whiteColor().CGColor)
 }

Which means the gradient background can now be applied to any UIControl since all controls are UIViews (or a subclass) and all UIViews have CALayers.

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

Swift 4

斯威夫特 4

Extension implementation

扩展实现

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

Extension use-case example:

扩展用例示例:

override func viewDidLoad() {
    super.viewDidLoad()

    self.view.layer.configureGradientBackground(UIColor.purple.cgColor, UIColor.blue.cgColor, UIColor.white.cgColor)
}

回答by Kendall Helmstetter Gelner

What you are looking for is CAGradientLayer. Every UIViewhas a layer - into that layer you can add sublayers, just as you can add subviews. One specific type is the CAGradientLayer, where you give it an array of colors to gradiate between.

您正在寻找的是CAGradientLayer. 每个UIView层都有一个层 - 您可以在该层中添加子层,就像您可以添加子视图一样。一种特定类型是CAGradientLayer,您可以在其中为其提供一组颜色以进行渐变。

One example is this simple wrapper for a gradient view:

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

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

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

Note that you need to include the QuartZCore framework in order to access all of the layer parts of a UIView.

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