Aplicación de background degradado para UIView utilizando layout automático

Extendí UIView para agregar un método addGradientWithColor () para get el background de degradado:

extension UIView { func addGradientWithColor() { let gradient = CAGradientLayer() gradient.frame = self.bounds gradient.colors = [gradientEndColor.CGColor, gradientStartColor.CGColor] gradient.startPoint = CGPointMake(1,0) gradient.endPoint = CGPointMake(0.2,1) self.layer.insertSublayer(gradient, atIndex: 0) } } 

Mi problema es cuando ejecuto el modo horizontal, la UIView no está estirada

 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() self.view.addGradientWithColor() } 

Intenté llamar a viewDidLayoutSubviews () pero no funciona correctamente

Aquí está la captura de pantalla:

después de quitar viewDidLayoutSubviews () introduzca la descripción de la imagen aquí

Puede subclassar UIView y anular el método drawRect donde agrega su gradiente.

 class GradientView: UIView { private let gradient : CAGradientLayer = CAGradientLayer() override func layoutSublayers(of layer: CALayer) { super.layoutSublayersOfLayer(layer) self.gradient.frame = self.bounds } override public func draw(_ rect: CGRect) { self.gradient.frame = self.bounds self.gradient.colors = [gradientEndColor.CGColor, gradientStartColor.CGColor] self.gradient.startPoint = CGPoint.init(x: 1, y: 0) self.gradient.endPoint = CGPoint.init(x: 0.2, y: 1) if self.gradient.superlayer == nil { self.layer.insertSublayer(self.gradient, at: 0) } } 

}

Después de crear su UIView, solo necesita agregar sus restricciones a esa vista.

puede save una reference a la capa y ajustar su marco en el método layoutSublayersOfLayer vistas. esto podría subcontratarse en una subclass UIView:

 class GradientView: UIView { private let gradient : CAGradientLayer = CAGradientLayer() /** displays a gradient on the view */ func addGradient() { self.gradient.frame = self.bounds self.gradient.colors = [gradientEndColor.CGColor, gradientStartColor.CGColor] gradient.startPoint = CGPointMake(1,0) gradient.endPoint = CGPointMake(0.2,1) self.layer.insertSublayer(self.gradient, atIndex: 0) } /** resizes the gradient with the view size */ override func layoutSublayers(of layer: CALayer) { super.layoutSublayers(of: layer) self.gradient.frame = self.bounds } } 

Las capas no se autorizan por sí mismas. Para solucionar este problema, debe cambiar el marco de la capa. Esta es una forma de cómo es posible implementar:

 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() //Update you're layer based on the new frame self.view.addGradientWithColor() } 

Inspirado en soluciones aquí, he creado la siguiente class.

Ejemplos de uso:

 // Simple usage. From clear to black. let gradientView1 = GradientView(colors: [.clear, .black]) // Tweak locations. Here the gradient from networking to green will take 30% of the view. let gradientView2 = GradientView(colors: [.networking, .green, .blue], locations: [0, 0.3, 1]) // Create your own gradient. let gradient = CAGradientLayer() gradient.colors = [UIColor.networking.cgColor, UIColor.blue.cgColor] let gradientView3 = GradientView(gradient: gradient) 

La class:

 import UIKit /** * View with a gradient layer. */ class GradientView: UIView { let gradient : CAGradientLayer init(gradient: CAGradientLayer) { self.gradient = gradient super.init(frame: .zero) self.gradient.frame = self.bounds self.layer.insertSublayer(self.gradient, at: 0) } convenience init(colors: [UIColor], locations:[Float] = [0.0, 1.0]) { let gradient = CAGradientLayer() gradient.colors = colors.map { $0.cgColor } gradient.locations = locations.map { NSNumber(value: $0) } self.init(gradient: gradient) } override func layoutSublayers(of layer: CALayer) { super.layoutSublayers(of: layer) self.gradient.frame = self.bounds } requinetworking init?(coder: NSCoder) { fatalError("no init(coder:)") } }