Criar programaticamente uma UIView com gradiente de cores

estou a tentar gerar uma vista com um fundo de cor gradiente (uma cor sólida A transparente) em execução. Há alguma maneira de fazer isso?

Author: Edward, 2014-04-15

18 answers

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

Informação: usar o ponto de partida e o ponto final para mudar a direcção do gradiente .

Se existirem outras vistas adicionadas a este UIView (Tal como um UILabel), poderá querer considerar a opção Definir a cor de fundo dessas UIView's para [UIColor clearColor] por isso a vista gradiente é apresentada em vez da cor de fundo das sub-vistas. A utilização de clearColor tem um ligeiro impacto no desempenho.

 611
Author: Arslan Ali, 2017-05-23 12:10:54

Você pode criar uma classe personalizadaGradientView:

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

No storyboard, defina o tipo de classe para qualquer Vista que queira ter fundo gradiente:

enter image description here

Isto é melhor das seguintes formas:

  • não é necessário definir a moldura de CLayer
  • utilizar NSConstraint como de costume no UIView
  • não é necessário criar sub-camadas (menos uso de memória)
 35
Author: Yuchen Zhong, 2018-02-20 13:34:06
Esta é a minha abordagem recomendada.

Para promover a reutilização, eu diria criar uma categoria de CAGradientLayer e adicionar os gradientes desejados como métodos de classe. Indique - os no ficheiro header assim:

#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

Depois, no seu ficheiro de implementação, indique cada gradiente com esta sintaxe:

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

Depois, basta importar esta categoria no seu ViewController ou em qualquer outro subclass necessário, e usá-la assim:

CAGradientLayer *backgroundLayer = [CAGradientLayer purpleGradientLayer];
backgroundLayer.frame = self.view.frame;
[self.view.layer insertSublayer:backgroundLayer atIndex:0];
 34
Author: Sam Fischer, 2014-04-15 04:26:56
Tenta isto. funcionou como um encanto para mim.

Objectivo C

Mudei RGB gradiente de cor de fundo para 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

Actualizado: - Swift3 +

Código :-

 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

Pode adicionar o ponto inicial e final da cor do gradiente.

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

enter image description here

Para mais detalhes, Descrição ver CAGradientLayer Doc

Espero que isto seja Ajuda para alguém .
 27
Author: Jaywant Khedkar, 2018-08-31 09:43:56

Uma vez que só precisava de um tipo de gradiente ao longo do meu aplicativo, criei uma subclasse de UIView e pré-configurei a camada de gradiente na inicialização com cores fixas. Os inicializadores do UIView chamam o método configuragradientlayer , que configura o método 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
 18
Author: blauzahn, 2016-09-28 10:28:19

Execução Rápida:

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)
 12
Author: Siva Visakan, 2015-02-09 20:27:22

Implementei isto no swift com uma extensão:

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

Não posso definir um gradiente em cada vista como esta:

myImageView.addGradientWithColor(UIColor.blue)
 8
Author: patrickS, 2016-10-13 09:41:32

Ampliei um pouco a resposta aceite usando a funcionalidade de extensão da Swift, bem como um enum.

Se está a usar o Storyboard como eu, não se esqueça de ligar para gradientBackground(from:to:direction:)em viewDidLayoutSubviews() ou mais tarde.

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)
    }
}
 7
Author: arm0nic, 2017-06-14 21:45:14

Uma Abordagem Rápida

Esta resposta baseia-se nas respostas acima e fornece implementação para lidar com o problema do gradiente não ser aplicado corretamente durante a rotação. Ele satisfaz este problema mudando a camada gradiente para um quadrado de modo que a rotação em todas as direções resulta em um gradiente correto. A assinatura da função inclui um argumento Variádico Swift que permite passar em tantos CGColorRef (CGColor) quanto necessário (veja uso de amostra). Tambem desde que seja um exemplo como uma extensão rápida para que se possa aplicar um gradiente a qualquer 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)
    }

A utilizar:

em vista...

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

Extensão da execução

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

O que significa que o gradiente de fundo pode agora ser aplicado a qualquer UIControl, uma vez que todos os controlos são UIViews (ou uma subclasse) e todos os UIViews têm CALayers.

Swift 4

extensão execução

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

exemplo de caso de Utilização da extensão:

override func viewDidLoad() {
    super.viewDidLoad()

    self.view.layer.configureGradientBackground(UIColor.purple.cgColor, UIColor.blue.cgColor, UIColor.white.cgColor)
}
 6
Author: Tommie C., 2018-03-20 14:57:46

O que estás à procura é {[[0]}. Cada UIView tem uma camada-nessa camada você pode adicionar sub-camadas, assim como você pode adicionar subviews. Um tipo específico é o CAGradientLayer, onde você lhe dá um array de cores para graduar entre.

Um exemplo é este invólucro simples para uma vista de gradiente:

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

Note que você precisa incluir o framework QuartZCore para acessar todas as partes da camada de um UIView.

 5
Author: Kendall Helmstetter Gelner, 2014-04-15 04:18:15

Visão rápida simples baseada na versão de Yuchen

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

}

Então você pode usar gradientLayer após inicialização como esta...

someView.gradientLayer.colors = [UIColor.whiteColor().CGColor, UIColor.blackColor().CGColor]
 3
Author: GregP, 2016-08-26 07:22:39

A minha solução é criar uma subclasse UIView com CAGradientLayer acessível como uma propriedade só de leitura. Isto permitirá que você personalize seu gradiente como você deseja e você não precisa lidar com alterações de layout você mesmo. Implementação da subclasse:

@interface GradientView : UIView

@property (nonatomic, readonly) CAGradientLayer *gradientLayer;

@end

@implementation GradientView

+ (Class)layerClass
{
    return [CAGradientLayer class];
}

- (CAGradientLayer *)gradientLayer
{
    return (CAGradientLayer *)self.layer;
}

@end

Utilização:

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);
 3
Author: Timur Bernikowich, 2017-01-26 09:01:42

Swift 4:

Mostra o gradiente em IB correctamente:

@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]
    }
}
 3
Author: Alexander Volkov, 2018-03-13 04:00:49

In Swift 3.1 Eu adicionei esta extensão a 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)
    }
}

Que eu depois chamo com

    class OverviewVC: UIViewController {

        override func viewDidLoad() {
            super.viewDidLoad()

            self.view.gradientOfView(withColours: UIColor.red,UIColor.green, UIColor.blue)

        }
}
 1
Author: iCyberPaul, 2017-04-16 15:17:47

É uma boa ideia chamar as soluções acima para actualizar a camada no

viewDidLayoutSubviews 

Para obter as vistas actualizadas correctamente

 1
Author: Tomate Albertini, 2017-10-26 17:02:07

SWIFT 3

Para adicionar uma camada de gradiente à sua vista

  • ligar a sua saída de vista

    @IBOutlet var YOURVIEW : UIView!
    
  • Define a camada de CAGradientLayer()

    var gradient = CAGradientLayer()
    
  • Aqui está o código que você tem que escrever no seu viewDidLoad

    topview.layoutIfNeeded()

    gradient.startPoint = CGPoint(x: CGFloat(0), y: CGFloat(1)) gradient.endPoint = CGPoint(x: CGFloat(1), y: CGFloat(0)) gradient.frame = topview.bounds gradient.frame = SearchView.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] topview.layer.insertSublayer(gradient, at: 0)

 1
Author: Azharhussain Shaikh, 2018-03-23 12:36:13
Implementei isto no meu código.
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];
Agora vejo um gradiente na minha visão.
 0
Author: Padmaja, 2016-08-24 10:57:56
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)
    }

}

Utilização

someView.applyGradient(isTopBottom: true, colorArray: [.green, .blue])
 0
Author: Harris, 2017-03-11 19:21:54