Cómo aplicar gradiente a la vista de background de la aplicación iOS Swift

Estoy intentando aplicar un degradado como el color de background de una Vista (vista principal de un storyboard). El código se ejecuta, pero nada cambia. Estoy usando xCode Beta 2 y Swift.

Aquí está el código:

class Colors { let colorTop = UIColor(networking: 192.0/255.0, green: 38.0/255.0, blue: 42.0/255.0, alpha: 1.0) let colorBottom = UIColor(networking: 35.0/255.0, green: 2.0/255.0, blue: 2.0/255.0, alpha: 1.0) let gl: CAGradientLayer init() { gl = CAGradientLayer() gl.colors = [ colorTop, colorBottom] gl.locations = [ 0.0, 1.0] } } 

luego en el controller de vista:

  let colors = Colors() func refresh() { view.backgroundColor = UIColor.clearColor() var backgroundLayer = colors.gl backgroundLayer.frame = view.frame view.layer.insertSublayer(backgroundLayer, atIndex: 0) } } } 

Los colors que proporciona al degradado deben ser del tipo CGColor . Así que configure su matriz de CGColor en gl.colors .

El código correcto es:

 class Colors { var gl:CAGradientLayer! init() { let colorTop = UIColor(networking: 192.0 / 255.0, green: 38.0 / 255.0, blue: 42.0 / 255.0, alpha: 1.0).cgColor let colorBottom = UIColor(networking: 35.0 / 255.0, green: 2.0 / 255.0, blue: 2.0 / 255.0, alpha: 1.0).cgColor self.gl = CAGradientLayer() self.gl.colors = [colorTop, colorBottom] self.gl.locations = [0.0, 1.0] } } 

Xcode 8.2 • Swift 3.0.2


Puede diseñar su propia vista gradiente de la siguiente manera:

 @IBDesignable class GradientView: UIView { @IBInspectable var startColor: UIColor = .black { didSet { updateColors() }} @IBInspectable var endColor: UIColor = .white { didSet { updateColors() }} @IBInspectable var startLocation: Double = 0.05 { didSet { updateLocations() }} @IBInspectable var endLocation: Double = 0.95 { didSet { updateLocations() }} @IBInspectable var horizontalMode: Bool = false { didSet { updatePoints() }} @IBInspectable var diagonalMode: Bool = false { didSet { updatePoints() }} override class var layerClass: AnyClass { return CAGradientLayer.self } var gradientLayer: CAGradientLayer { return layer as! CAGradientLayer } func updatePoints() { if horizontalMode { gradientLayer.startPoint = diagonalMode ? CGPoint(x: 1, y: 0) : CGPoint(x: 0, y: 0.5) gradientLayer.endPoint = diagonalMode ? CGPoint(x: 0, y: 1) : CGPoint(x: 1, y: 0.5) } else { gradientLayer.startPoint = diagonalMode ? CGPoint(x: 0, y: 0) : CGPoint(x: 0.5, y: 0) gradientLayer.endPoint = diagonalMode ? CGPoint(x: 1, y: 1) : CGPoint(x: 0.5, y: 1) } } func updateLocations() { gradientLayer.locations = [startLocation as NSNumber, endLocation as NSNumber] } func updateColors() { gradientLayer.colors = [startColor.cgColor, endColor.cgColor] } override func layoutSubviews() { super.layoutSubviews() updatePoints() updateLocations() updateColors() } } 

introduzca la descripción de la imagen aquí

Y si necesita cambiar la dirección del gradiente, debe utilizar startPoint y endPoint.

 let gradient: CAGradientLayer = CAGradientLayer() gradient.colors = [UIColor.blue.cgColor, UIColor.networking.cgColor] gradient.locations = [0.0 , 1.0] gradient.startPoint = CGPoint(x: 0.0, y: 1.0) gradient.endPoint = CGPoint(x: 1.0, y: 1.0) gradient.frame = CGRect(x: 0.0, y: 0.0, width: self.view.frame.size.width, height: self.view.frame.size.height) self.view.layer.insertSublayer(gradient, atIndex: 0) 

Simplemente modificando la respuesta de mención anterior.

introduzca la descripción de la imagen aquí

 func setGradientBackground() { let colorTop = UIColor(networking: 255.0/255.0, green: 149.0/255.0, blue: 0.0/255.0, alpha: 1.0).CGColor let colorBottom = UIColor(networking: 255.0/255.0, green: 94.0/255.0, blue: 58.0/255.0, alpha: 1.0).CGColor let gradientLayer = CAGradientLayer() gradientLayer.colors = [ colorTop, colorBottom] gradientLayer.locations = [ 0.0, 1.0] gradientLayer.frame = self.view.bounds self.view.layer.insertSublayer(gradientLayer) } 

introduzca la descripción de la imagen aquí

Hice una extensión UIView para aplicar un degradado básico a cualquier vista

 extension UIView { func layerGradient() { let layer : CAGradientLayer = CAGradientLayer() layer.frame.size = self.frame.size layer.frame.origin = CGPointMake(0.0,0.0) layer.cornerRadius = CGFloat(frame.width / 20) let color0 = UIColor(networking:250.0/255, green:250.0/255, blue:250.0/255, alpha:0.5).CGColor let color1 = UIColor(networking:200.0/255, green:200.0/255, blue: 200.0/255, alpha:0.1).CGColor let color2 = UIColor(networking:150.0/255, green:150.0/255, blue: 150.0/255, alpha:0.1).CGColor let color3 = UIColor(networking:100.0/255, green:100.0/255, blue: 100.0/255, alpha:0.1).CGColor let color4 = UIColor(networking:50.0/255, green:50.0/255, blue:50.0/255, alpha:0.1).CGColor let color5 = UIColor(networking:0.0/255, green:0.0/255, blue:0.0/255, alpha:0.1).CGColor let color6 = UIColor(networking:150.0/255, green:150.0/255, blue:150.0/255, alpha:0.1).CGColor layer.colors = [color0,color1,color2,color3,color4,color5,color6] self.layer.insertSublayer(layer, atIndex: 0) } } 

En Swift3 testing esto:

  func addGradient(){ let gradient:CAGradientLayer = CAGradientLayer() gradient.frame.size = self.viewThatHoldsGradient.frame.size gradient.colors = [UIColor.white.cgColor,UIColor.white.withAlphaComponent(0).cgColor] //Or any colors self.viewThatHoldsGradient.layer.addSublayer(gradient) } 

Este código funcionará con Swift 3.0

 class GradientView: UIView { override open class var layerClass: AnyClass { get{ return CAGradientLayer.classForCoder() } } requinetworking init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) let gradientLayer = self.layer as! CAGradientLayer let color1 = UIColor.white.withAlphaComponent(0.1).cgColor as CGColor let color2 = UIColor.white.withAlphaComponent(0.9).cgColor as CGColor gradientLayer.locations = [0.60, 1.0] gradientLayer.colors = [color2, color1] } } 

Extienda UIView con esta class personalizada.


GradientView.swift

 import UIKit class GradientView: UIView { // Default Colors var colors:[UIColor] = [UIColor.networkingColor(), UIColor.blueColor()] override func drawRect(rect: CGRect) { // Must be set when the rect is drawn setGradient(colors[0], color2: colors[1]) } func setGradient(color1: UIColor, color2: UIColor) { let context = UIGraphicsGetCurrentContext() let gradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), [color1.CGColor, color2.CGColor], [0, 1])! // Draw Path let path = UIBezierPath(rect: CGRectMake(0, 0, frame.width, frame.height)) CGContextSaveGState(context) path.addClip() CGContextDrawLinearGradient(context, gradient, CGPointMake(frame.width / 2, 0), CGPointMake(frame.width / 2, frame.height), CGGradientDrawingOptions()) CGContextRestoreGState(context) } override func layoutSubviews() { // Ensure view has a transparent background color (not requinetworking) backgroundColor = UIColor.clearColor() } } 

Uso

gradientView.colors = [UIColor.blackColor().colorWithAlphaComponent(0.8), UIColor.clearColor()]


Resultado

introduzca la descripción de la imagen aquí

Tengo estas extensiones:

 @IBDesignable class GradientView: UIView { @IBInspectable var firstColor: UIColor = UIColor.networking @IBInspectable var secondColor: UIColor = UIColor.green @IBInspectable var vertical: Bool = true override func awakeFromNib() { super.awakeFromNib() applyGradient() } func applyGradient() { let colors = [firstColor.cgColor, secondColor.cgColor] let layer = CAGradientLayer() layer.colors = colors layer.frame = self.bounds layer.startPoint = CGPoint(x: 0, y: 0) layer.endPoint = vertical ? CGPoint(x: 0, y: 1) : CGPoint(x: 1, y: 0) self.layer.addSublayer(layer) } override func draw(_ rect: CGRect) { super.draw(rect) #if TARGET_INTERFACE_BUILDER applyGradient() #endif } } @IBDesignable class ThreeColorsGradientView: UIView { @IBInspectable var firstColor: UIColor = UIColor.networking @IBInspectable var secondColor: UIColor = UIColor.green @IBInspectable var thirdColor: UIColor = UIColor.blue @IBInspectable var vertical: Bool = true override func awakeFromNib() { super.awakeFromNib() applyGradient() } func applyGradient() { let colors = [firstColor.cgColor, secondColor.cgColor, thirdColor.cgColor] let layer = CAGradientLayer() layer.colors = colors layer.frame = self.bounds layer.startPoint = CGPoint(x: 0, y: 0) layer.endPoint = vertical ? CGPoint(x: 0, y: 1) : CGPoint(x: 1, y: 0) self.layer.addSublayer(layer) } override func draw(_ rect: CGRect) { super.draw(rect) #if TARGET_INTERFACE_BUILDER applyGradient() #endif } } @IBDesignable class RadialGradientView: UIView { @IBInspectable var outsideColor: UIColor = UIColor.networking @IBInspectable var insideColor: UIColor = UIColor.green override func awakeFromNib() { super.awakeFromNib() applyGradient() } func applyGradient() { let colors = [insideColor.cgColor, outsideColor.cgColor] as CFArray let endRadius = sqrt(pow(frame.width/2, 2) + pow(frame.height/2, 2)) let center = CGPoint(x: bounds.size.width / 2, y: bounds.size.height / 2) let gradient = CGGradient(colorsSpace: nil, colors: colors, locations: nil) let context = UIGraphicsGetCurrentContext() context?.drawRadialGradient(gradient!, startCenter: center, startRadius: 0.0, endCenter: center, endRadius: endRadius, options: CGGradientDrawingOptions.drawsBeforeStartLocation) } override func draw(_ rect: CGRect) { super.draw(rect) #if TARGET_INTERFACE_BUILDER applyGradient() #endif } } 

Uso:

introduzca la descripción de la imagen aquí

introduzca la descripción de la imagen aquí

introduzca la descripción de la imagen aquí

si desea utilizar HEX en lugar de RGBA, simplemente arrastre un nuevo .swift vacío y agregue el código mencionado a continuación:

  import UIKit extension UIColor { convenience init(rgba: String) { var networking: CGFloat = 0.0 var green: CGFloat = 0.0 var blue: CGFloat = 0.0 var alpha: CGFloat = 1.0 if rgba.hasPrefix("#") { let index = advance(rgba.startIndex, 1) let hex = rgba.substringFromIndex(index) let scanner = NSScanner(string: hex) var hexValue: CUnsignedLongLong = 0 if scanner.scanHexLongLong(&hexValue) { switch (count(hex)) { case 3: networking = CGFloat((hexValue & 0xF00) >> 8) / 15.0 green = CGFloat((hexValue & 0x0F0) >> 4) / 15.0 blue = CGFloat(hexValue & 0x00F) / 15.0 case 4: networking = CGFloat((hexValue & 0xF000) >> 12) / 15.0 green = CGFloat((hexValue & 0x0F00) >> 8) / 15.0 blue = CGFloat((hexValue & 0x00F0) >> 4) / 15.0 alpha = CGFloat(hexValue & 0x000F) / 15.0 case 6: networking = CGFloat((hexValue & 0xFF0000) >> 16) / 255.0 green = CGFloat((hexValue & 0x00FF00) >> 8) / 255.0 blue = CGFloat(hexValue & 0x0000FF) / 255.0 case 8: networking = CGFloat((hexValue & 0xFF000000) >> 24) / 255.0 green = CGFloat((hexValue & 0x00FF0000) >> 16) / 255.0 blue = CGFloat((hexValue & 0x0000FF00) >> 8) / 255.0 alpha = CGFloat(hexValue & 0x000000FF) / 255.0 default: print("Invalid RGB string, number of characters after '#' should be either 3, 4, 6 or 8") } } else { println("Scan hex error") } } else { print("Invalid RGB string, missing '#' as prefix") } self.init(networking:networking, green:green, blue:blue, alpha:alpha) } } 

de manera similar, arrastre otro file .swift vacío y agregue el código mencionado a continuación:

  class Colors { let colorTop = UIColor(rgba: "##8968CD").CGColor let colorBottom = UIColor(rgba: "#5D478B").CGColor let gl: CAGradientLayer init() { gl = CAGradientLayer() gl.colors = [ colorTop, colorBottom] gl.locations = [ 0.0, 1.0] } } 

después de eso, en el controller de vista, en la class instanciar tu class 'Color' así:

 let colors = Colors() 

agregar una nueva function:

 func refresh() { view.backgroundColor = UIColor.clearColor() var backgroundLayer = colors.gl backgroundLayer.frame = view.frame view.layer.insertSublayer(backgroundLayer, atIndex: 0) } 

indique esa function en viewDidLoad:

 refresh() 

ya está :)) usar HEX es muy fácil si se compara con RGBA. :RE

Swift 3: usa solo texturas y SKSpriteNode, no requiere UIView

 import Foundation import SpriteKit class GradientSpriteNode : SKSpriteNode { convenience init(size: CGSize, colors: [UIColor], locations: [CGFloat]) { let texture = GradientSpriteNode.texture(size: size, colors: colors, locations: locations) self.init(texture: texture, color:SKColor.clear, size: texture.size()) } private override init(texture: SKTexture!, color: SKColor, size: CGSize) { super.init(texture: texture, color: color, size: size) } requinetworking init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } private static func texture(size: CGSize, colors: [UIColor], locations: [CGFloat]) -> SKTexture { UIGraphicsBeginImageContext(size) let context = UIGraphicsGetCurrentContext()! let gradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors.map{$0.cgColor} as CFArray, locations: locations)! context.drawLinearGradient(gradient, start: CGPoint(x: size.width / 2, y: 0), end: CGPoint(x: size.width / 2, y: size.height), options: CGGradientDrawingOptions()) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return SKTexture(image: image!) } } 

Uso:

 let gradient = GradientSpriteNode( size: CGSize(width: 100, height: 100), colors: [UIColor.networking, UIColor.blue], locations: [0.0, 1.0]) addChild(gradient) 

Aquí hay una extensión rápida donde puede pasar cualquier cantidad de colors arbitrarios. Eliminará los gradientes previos antes de insert uno y devolverá la capa de gradiente recién insertada para una mayor manipulación si es necesario:

  extension UIView { /** Given an Array of CGColor, it will: - Remove all sublayers of type CAGradientLayer. - Create and insert a new CAGradientLayer. - Parameters: - colors: An Array of CGColor with the colors for the gradient fill - Returns: The newly created gradient CAGradientLayer */ func layerGradient(colors c:[CGColor])->CAGradientLayer { self.layer.sublayers = self.layer.sublayers?.filter(){!($0 is CAGradientLayer)} let layer : CAGradientLayer = CAGradientLayer() layer.frame.size = self.frame.size layer.frame.origin = CGPointZero layer.colors = c self.layer.insertSublayer(layer, atIndex: 0) return layer } } 

Simplemente especifique el marco de la vista, donde desea mostrar el color del gradiente.

 let firstColor = UIColor(networking: 69/255, green: 90/255, blue: 195/255, alpha: 1.0).CGColor let secondColor = UIColor(networking: 230/255, green: 44/255, blue: 75/255, alpha: 1.0).CGColor let gradientLayer = CAGradientLayer() gradientLayer.colors = [ firstColor, secondColor] gradientLayer.locations = [ 0.0, 1.0] gradientLayer.frame = CGRectMake(0, 0, 375, 64)// You can mention frame here self.view.layer.addSublayer(gradientLayer) 

Código más limpio que le permite pasar cualquier UIColor a una instancia de la class GradientLayer :

 class GradientLayer { let gradientLayer: CAGradientLayer let colorTop: CGColor let colorBottom: CGColor init(colorTop: UIColor, colorBottom: UIColor) { self.colorTop = colorTop.CGColor self.colorBottom = colorBottom.CGColor gradientLayer = CAGradientLayer() gradientLayer.colors = [colorTop, colorBottom] gradientLayer.locations = [0.0, 1.0] } } 

Aquí hay una variación para configurar esto en un file de class Util reutilizable

En su proyecto Xcode:

  1. Cree una nueva class Swift que la llame UI_Util.swift y rellénela de la siguiente manera:

     import Foundation import UIKit class UI_Util { static func setGradientGreenBlue(uiView: UIView) { let colorTop = UIColor(networking: 15.0/255.0, green: 118.0/255.0, blue: 128.0/255.0, alpha: 1.0).cgColor let colorBottom = UIColor(networking: 84.0/255.0, green: 187.0/255.0, blue: 187.0/255.0, alpha: 1.0).cgColor let gradientLayer = CAGradientLayer() gradientLayer.colors = [ colorTop, colorBottom] gradientLayer.locations = [ 0.0, 1.0] gradientLayer.frame = uiView.bounds uiView.layer.insertSublayer(gradientLayer, at: 0) } } 

  1. Ahora puede llamar a la function desde cualquier ViewController así:

     class AbcViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() UI_Util.setGradientGreen(uiView: self.view) } 

Gracias a la respuesta de katwal-Dipak para el código de function

Si tiene la vista Colección (Vista múltiple), haga esto

  func setGradientBackground() { let v:UIView for v in viewgradian //here viewgradian is your view Collection Outlet name { let layer:CALayer var arr = [AnyObject]() for layer in v.layer.sublayers! { arr.append(layer) } let colorTop = UIColor(networking: 216.0/255.0, green: 240.0/255.0, blue: 244.0/255.0, alpha: 1.0).cgColor let colorBottom = UIColor(networking: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1.0).cgColor let gradientLayer = CAGradientLayer() gradientLayer.colors = [ colorBottom, colorTop] gradientLayer.startPoint = CGPoint(x: 1.0, y: 0.0) gradientLayer.endPoint = CGPoint(x: 0.0, y: 1.0) gradientLayer.frame = v.bounds v.layer.insertSublayer(gradientLayer, at: 0) } } 

Extensión fácil de usar en swift 3

 extension CALayer { func addGradienBorder(colors:[UIColor] = [UIColor.networking,UIColor.blue], width:CGFloat = 1) { let gradientLayer = CAGradientLayer() gradientLayer.frame = CGRect(origin: .zero, size: self.bounds.size) gradientLayer.startPoint = CGPoint(x:0.0, y:0.5) gradientLayer.endPoint = CGPoint(x:1.0, y:0.5) gradientLayer.colors = colors.map({$0.cgColor}) let shapeLayer = CAShapeLayer() shapeLayer.lineWidth = width shapeLayer.path = UIBezierPath(rect: self.bounds).cgPath shapeLayer.fillColor = nil shapeLayer.strokeColor = UIColor.black.cgColor gradientLayer.mask = shapeLayer self.addSublayer(gradientLayer) } } 

use a su vista, ejemplo

 yourView.setShadowWithColor(color: UIColor.black, opacity: 0.1, offset: CGSize(width:2 , height: 5), radius: 3, viewCornerRadius: 3.0) 

Prueba esto, está funcionando para mí,

  let gradientLayer:CAGradientLayer = CAGradientLayer() gradientLayer.frame.size = self.gradientView.frame.size gradientLayer.colors = [UIColor.white.cgColor,UIColor.networking.withAlphaComponent(1).cgColor] //Use diffrent colors self.gradientView.layer.addSublayer(gradientLayer) 

introduzca la descripción de la imagen aquí

Puede agregar el punto inicial y final del color del gradiente.

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

introduzca la descripción de la imagen aquí

Esperanzas Esto es ayuda para alguien.