J'ai du mal à ajouter un fond dégradé à UIView
. J'ai fait un extension
de UIView
et j'ai ajouté la méthode suivante:
func setGradientBackground(colorTop: UIColor, colorBottom: UIColor) {
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorTop, colorBottom]
gradientLayer.frame = bounds
layer.insertSublayer(gradientLayer, at: 0)
}
Ensuite j'appelle:
separatorView.setGradientBackground(colorTop: .clear, colorBottom: .red)
Mais ça ne marche pas. La vue est présentée mais son arrière-plan est parfaitement net. J'ai aussi essayé avec CGColor
Il y avait 2 problèmes:
Je devais définir les points de début et de fin pour fournir une direction de dégradé:
func setGradientBackground(colorTop: UIColor, colorBottom: UIColor) {
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorBottom.cgColor, colorTop.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.locations = [0, 1]
gradientLayer.frame = bounds
layer.insertSublayer(gradientLayer, at: 0)
}
Et le deuxième problème était que CAGradientLayer
prend effet après la présentation de la vue. J'ai résolu que l'appel de setGradientBackground()
sur viewDidAppear
:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
separatorView.setGradientBackground(colorTop: .clear, colorBottom: Colors.darkGrey)
}
La réponse de Moayad a fonctionné le mieux pour moi, mais c'était à l'envers avec la couleur du haut comme bas, j'ai donc inversé la fonction qu'il a publiée.
Swift 4
func setGradientBackground(colorTop: UIColor, colorBottom: UIColor){
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorBottom.cgColor, colorTop.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.locations = [0, 1]
gradientLayer.frame = bounds
layer.insertSublayer(gradientLayer, at: 0)
}
Mettez à jour votre méthode au coup de code:
func setGradientBackground(colorTop: UIColor, colorBottom: UIColor){
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorTop.cgColor, colorBottom.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.locations = [NSNumber(floatLiteral: 0.0), NSNumber(floatLiteral: 1.0)]
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at: 0)
}
Pour @IBDesignable: vous pouvez personnaliser votre interface utilisateur sur le storyboard. Il est plus simple à utiliser.
@IBDesignable class GradientView: UIView {
@IBInspectable var startColor: UIColor = .blue {
didSet {
setNeedsLayout()
}
}
@IBInspectable var endColor: UIColor = .green {
didSet {
setNeedsLayout()
}
}
@IBInspectable var shadowColor: UIColor = .yellow {
didSet {
setNeedsLayout()
}
}
@IBInspectable var shadowX: CGFloat = 0 {
didSet {
setNeedsLayout()
}
}
@IBInspectable var shadowY: CGFloat = -3 {
didSet {
setNeedsLayout()
}
}
@IBInspectable var shadowBlur: CGFloat = 3 {
didSet {
setNeedsLayout()
}
}
@IBInspectable var startPointX: CGFloat = 0 {
didSet {
setNeedsLayout()
}
}
@IBInspectable var startPointY: CGFloat = 0 {
didSet {
setNeedsLayout()
}
}
@IBInspectable var endPointX: CGFloat = 0 {
didSet {
setNeedsLayout()
}
}
@IBInspectable var endPointY: CGFloat = 0 {
didSet {
setNeedsLayout()
}
}
@IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
setNeedsLayout()
}
}
override class var layerClass: AnyClass {
return CAGradientLayer.self
}
override func layoutSubviews() {
let gradientLayer = layer as! CAGradientLayer
gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
gradientLayer.startPoint = CGPoint(x: startPointX, y: startPointY)
gradientLayer.endPoint = CGPoint(x: endPointX, y: endPointY)
layer.cornerRadius = cornerRadius
layer.shadowColor = shadowColor.cgColor
layer.shadowOffset = CGSize(width: shadowX, height: shadowY)
layer.shadowRadius = shadowBlur
layer.shadowOpacity = 1
}
}
la réponse de gmoraleda est correcte. Faites-le sur viewDidLayoutSubviews
si vous utilisez AutoLayout.
Cela fonctionne pour mon projet
/**
set a gradient to a view
gradientColors must be cgColors
gradientColors and locations must have the same array size
example:
let gradientColors = [UIColor.red.cgColor,UIColor.blue.cgColor,UIColor.yellow.cgColor]
let locations:[NSNumber] = [0.0,0.8,1.0]
*/
static func setGradient(viewWithGradient: UIView, backgroundColor: UIColor, gradientColors: [CGColor], locations:[NSNumber], boundsOfGradient:CGRect) {
if gradientColors.count != locations.count {
print("gradientColors and locations must have same size!")
return
}
viewWithGradient.backgroundColor = backgroundColor
let mask = CAGradientLayer()
mask.colors = gradientColors
mask.locations = locations
mask.frame = boundsOfGradient
viewWithGradient.layer.mask = mask
}
Appel comme ça
let gradientColors = [UIColor.red.cgColor,UIColor.blue.cgColor,UIColor.yellow.cgColor]
let locations:[NSNumber] = [0.0,0.8,1.0]
GeneralTools.setGradient(viewWithGradient: yourViewThatShouldGetGradient, backgroundColor: backgroundColorOfYourViewWithGradient, gradientColors: gradientColors, locations: locations, boundsOfGradient: viewWhereIsYourGradientInside.bounds)
Peut-être pas assez clair boundsOfGradient
: Les limites seront définies sur votre cadre de dégradés. Donc, simplement dit, cela déclarera la taille de votre dégradé.