Créer par programme une UIView avec un dégradé de couleurs
292
J'essaie de générer une vue avec un arrière-plan de couleur dégradé (une couleur unie à transparente) au moment de l'exécution. Y a-t-il un moyen de le faire?
Si d'autres vues y sont ajoutées UIView(telles que a UILabel), vous pouvez envisager de définir la couleur d'arrière-plan de celles UIView-ci pour [UIColor clearColor]que la vue dégradée soit présentée à la place de la couleur d'arrière-plan des sous-vues. L'utilisation clearColora un léger impact sur les performances.
+1 pour la quantité de code la plus courte de toutes les solutions. J'ai juste ajouté à mon contrôleur de vue existant, changé les 2 refs viewen self.viewet cela a fonctionné comme un charme :)
Ergin
4
Il est également pertinent de savoir où ajouter ce code. J'avais besoin du post suivant pour que cela fonctionne: stackoverflow.com/a/20059268/1480518
Garrett Disco
13
Cela m'a beaucoup aidé! Vous avez manqué la partie CGColor partout ailleurs! Merci
Gyfis
48
N'oubliez pas d'utiliser 'startPoint' et 'endPoint' pour changer la direction du dégradé. Les valeurs par défaut sont (0,5, 0) et (0,5,1) - de haut en bas.
Valentin Shamardin
12
Quand mon UIView utilise AutoLayout, je devais aussi appeler gradient.frame = view.boundsen viewDidAppear()et didRotateFromInterfaceOrientation()ou bien le gradient ne serait pas la bonne taille.
EricRobertBrewer
70
Vous pouvez créer une classe personnalisée GradientView:
Bonjour @LaloLoop, merci pour le commentaire! J'ai mis à jour le code. Je ne pense pas que je doive passer outre init(frame:CGRect). J'ai testé le code mis à jour et cela fonctionne très bien.
Yuchen Zhong
@Yuchen Zhong Il se bloque dans IB, mais fonctionne dans l'application. Y a-t-il des raisons pour lesquelles il n'est pas rendu dans IB s'il @IBDesignableest utilisé?
Alexander Volkov
@AlexanderVolkov Probablement un autre problème? Nous l'avons utilisé comme tel dans le storyboard et ne semble pas avoir de problème cependant. Vous pouvez déboguer votre storyboard et voir quelle ligne le plante.
Yuchen Zhong
1
Meilleure solution !
Baran Emre
40
Essayez ça a fonctionné comme un charme pour moi,
Objectif c
J'ai défini la couleur d'arrière-plan du dégradé RVB sur UIview
Pour promouvoir la réutilisabilité, je dirais de créer une catégorie CAGradientLayeret d'ajouter vos dégradés souhaités comme méthodes de classe. Spécifiez-les dans le headerfichier comme ceci:
où mettre le code pour l'utiliser? quelle méthode de cycle de vie? viewdidappear fait apparaître une seconde trop tard. viewdidload et viewdidappear l'empêchent de fonctionner lors de la rotation. viewdidlayoutsubviews fonctionne mieux pour la rotation mais finit toujours par sembler un peu saccadé.
Adam Johns
Personnellement, je l'ai misviewDidLoad
Sam Fischer
1
Quand je l'ai mis viewDidLoad, cela n'a pas fonctionné si l'application a été lancée en orientation paysage. Ma solution était de rendre le cadre du calque d'arrière-plan plus large que le cadre view.frame pour compenser les autres orientations.
Adam Johns
2
viewDidLoad fonctionne, il vous suffit également de définir AutoResizingMask en utilisant [backgroundLayer setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
ekscrypto
21
Comme je n'avais besoin que d'un seul type de dégradé dans mon application, j'ai créé une sous-classe d'UIView et préconfiguré la couche de dégradé lors de l'initialisation avec des couleurs fixes. Les initialiseurs d'UIView appellent la méthode configureGradientLayer , qui configure le CAGradientLayer:
#import "DDGradientView.h"@implementationDDGradientView// Change the views layer class to CAGradientLayer class+(Class)layerClass
{return[CAGradientLayerclass];}-(instancetype)initWithCoder:(NSCoder*)aDecoder {self=[super initWithCoder:aDecoder];if(self){[self configureGradientLayer];}returnself;}-(instancetype)initWithFrame:(CGRect)frame {self=[super initWithFrame:frame];if(self){[self configureGradientLayer];}returnself;}// 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
J'ai un peu étendu la réponse acceptée en utilisant la fonctionnalité d'extension de Swift ainsi qu'une énumération.
Oh , et si vous utilisez Storyboard comme je le fais, assurez - vous d'appeler gradientBackground(from:to:direction:)à viewDidLayoutSubviews()ou plus tard.
Swift 3
enumGradientDirection{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)}}
L'appel Swift3 doit être comme: myImageView.addGradientWithColor (couleur: UIColor.blue)
mgyky
8
Une approche rapide
Cette réponse s'appuie sur les réponses ci-dessus et fournit une implémentation permettant de traiter le problème de la mauvaise application du gradient pendant la rotation. Il résout ce problème en changeant la couche de dégradé en un carré de sorte que la rotation dans toutes les directions entraîne un gradient correct. La signature de la fonction inclut un argument variadique Swift qui permet de passer autant de CGColorRef (CGColor) que nécessaire (voir exemple d'utilisation). Un exemple d'extension Swift est également fourni afin que l'on puisse appliquer un dégradé à n'importe quelle vue UIV.
Ce qui signifie que l'arrière-plan dégradé peut maintenant être appliqué à n'importe quel UIControl car tous les contrôles sont des UIViews (ou une sous-classe) et tous les UIViews ont des CALayers.
Ce que vous cherchez, c'est CAGradientLayer. Chacun UIViewa une couche - dans cette couche, vous pouvez ajouter des sous-couches, tout comme vous pouvez ajouter des sous-vues. Un type spécifique est le CAGradientLayer, où vous lui donnez un tableau de couleurs à graduer.
Un exemple est ce simple wrapper pour une vue en dégradé:
Ma solution est de créer une UIViewsous-classe avec CAGradientLayeraccessible en tant que propriété en lecture seule. Cela vous permettra de personnaliser votre dégradé comme vous le souhaitez et vous n'avez pas besoin de gérer vous-même les modifications de mise en page. Mise en œuvre de la sous-classe:
J'ai utilisé cette approche, en changeant "topview" pour le nom de mon IBoutlet pour ma vue. J'ai supprimé la ligne "SearchView".
jessi
Bon plan - notez peut-être aussi que vous pouvez utiliser l'une des configurations de gradient.colors. Donc, si vous commentez les dégradés.couleurs simples en utilisant des couleurs d'interface utilisateur nommées, l'image est la même, mais si vous commentez l'autre, le dégradé de couleurs dépend alors du rouge au vert. Les utilisateurs peuvent faire l'un ou l'autre.
jessi
1
Dans Swift 3.1, j'ai ajouté cette extension à UIView
Réponses:
Objectif c:
Rapide:
Info : utilisez startPoint et endPoint pour changer la direction du dégradé .
Si d'autres vues y sont ajoutées
UIView
(telles que aUILabel
), vous pouvez envisager de définir la couleur d'arrière-plan de cellesUIView
-ci pour[UIColor clearColor]
que la vue dégradée soit présentée à la place de la couleur d'arrière-plan des sous-vues. L'utilisationclearColor
a un léger impact sur les performances.la source
view
enself.view
et cela a fonctionné comme un charme :)gradient.frame = view.bounds
enviewDidAppear()
etdidRotateFromInterfaceOrientation()
ou bien le gradient ne serait pas la bonne taille.Vous pouvez créer une classe personnalisée
GradientView
:Swift 5
Dans le storyboard, définissez le type de classe sur n'importe quelle vue que vous souhaitez avoir un arrière-plan dégradé:
C'est mieux des manières suivantes:
CLayer
NSConstraint
comme d'habitude sur leUIView
la source
layerClass
n'est plus une fonction, c'est une propriété, vous devez donc la remplacer comme une propriété: stackoverflow.com/questions/28786597/… . Vous devez également implémenteroverride init(frame: CGRect)
, vérifiez cette réponse: stackoverflow.com/questions/27374330/… . Merci!init(frame:CGRect)
. J'ai testé le code mis à jour et cela fonctionne très bien.@IBDesignable
est utilisé?Essayez ça a fonctionné comme un charme pour moi,
Objectif c
J'ai défini la couleur d'arrière-plan du dégradé RVB sur UIview
MISE À JOUR: - Swift3 +
Code : -
Vous pouvez ajouter le point de départ et de fin de la couleur du dégradé.
Pour plus de détails, voir CAGradientLayer Doc
J'espère que c'est de l'aide pour quelqu'un.
la source
C'est mon approche recommandée.
Pour promouvoir la réutilisabilité, je dirais de créer une catégorie
CAGradientLayer
et d'ajouter vos dégradés souhaités comme méthodes de classe. Spécifiez-les dans leheader
fichier comme ceci:Ensuite, dans votre fichier d'implémentation, spécifiez chaque gradient avec cette syntaxe:
Ensuite, importez simplement cette catégorie dans votre
ViewController
ou toute autre exigencesubclass
, et utilisez-la comme ceci:la source
viewDidLoad
viewDidLoad
, cela n'a pas fonctionné si l'application a été lancée en orientation paysage. Ma solution était de rendre le cadre du calque d'arrière-plan plus large que le cadre view.frame pour compenser les autres orientations.Comme je n'avais besoin que d'un seul type de dégradé dans mon application, j'ai créé une sous-classe d'UIView et préconfiguré la couche de dégradé lors de l'initialisation avec des couleurs fixes. Les initialiseurs d'UIView appellent la méthode configureGradientLayer , qui configure le CAGradientLayer:
DDGradientView.h:
DDGradientView.m:
la source
initGradientLayer
est similaire à un initialiseur. Je ne pense pas que ce soit très approprié.Mise en œuvre rapide:
la source
J'ai un peu étendu la réponse acceptée en utilisant la fonctionnalité d'extension de Swift ainsi qu'une énumération.
Oh , et si vous utilisez Storyboard comme je le fais, assurez - vous d'appeler
gradientBackground(from:to:direction:)
àviewDidLayoutSubviews()
ou plus tard.Swift 3
la source
J'ai implémenté cela en swift avec une extension:
Swift 3
Swift 2.2
Non, je peux définir un dégradé sur chaque vue comme ceci:
la source
Une approche rapide
Cette réponse s'appuie sur les réponses ci-dessus et fournit une implémentation permettant de traiter le problème de la mauvaise application du gradient pendant la rotation. Il résout ce problème en changeant la couche de dégradé en un carré de sorte que la rotation dans toutes les directions entraîne un gradient correct. La signature de la fonction inclut un argument variadique Swift qui permet de passer autant de CGColorRef (CGColor) que nécessaire (voir exemple d'utilisation). Un exemple d'extension Swift est également fourni afin que l'on puisse appliquer un dégradé à n'importe quelle vue UIV.
Utiliser:
dans viewDidLoad ...
Implémentation d'extension
Exemple de cas d'utilisation d'extension:
Ce qui signifie que l'arrière-plan dégradé peut maintenant être appliqué à n'importe quel UIControl car tous les contrôles sont des UIViews (ou une sous-classe) et tous les UIViews ont des CALayers.
Swift 4
Implémentation d'extension
Exemple de cas d'utilisation d'extension:
la source
Ce que vous cherchez, c'est
CAGradientLayer
. ChacunUIView
a une couche - dans cette couche, vous pouvez ajouter des sous-couches, tout comme vous pouvez ajouter des sous-vues. Un type spécifique est leCAGradientLayer
, où vous lui donnez un tableau de couleurs à graduer.Un exemple est ce simple wrapper pour une vue en dégradé:
http://oleb.net/blog/2010/04/obgradientview-a-simple-uiview-wrapper-for-cagradientlayer/
Notez que vous devez inclure le framework QuartZCore afin d'accéder à toutes les parties de couche d'une UIView.
la source
Swift 4:
Affiche correctement le gradient dans IB:
la source
USAGE
la source
Vue simple et rapide basée sur la version de Yuchen
Ensuite, vous pouvez utiliser gradientLayer après l'initialisation comme ceci ...
la source
Ma solution est de créer une
UIView
sous-classe avecCAGradientLayer
accessible en tant que propriété en lecture seule. Cela vous permettra de personnaliser votre dégradé comme vous le souhaitez et vous n'avez pas besoin de gérer vous-même les modifications de mise en page. Mise en œuvre de la sous-classe:Usage:
la source
C'est une bonne idée d'appeler les solutions ci-dessus pour mettre à jour la couche sur le
pour que les vues soient correctement mises à jour
la source
SWIFT 3
Pour ajouter un calque de dégradé sur votre vue
Liez votre point de vue
Définissez le CAGradientLayer ()
Voici le code que vous devez écrire dans votre viewDidLoad
YOURVIEW.layoutIfNeeded()
gradient.startPoint = CGPoint(x: CGFloat(0), y: CGFloat(1)) gradient.endPoint = CGPoint(x: CGFloat(1), y: CGFloat(0)) gradient.frame = YOURVIEW.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] YOURVIEW.layer.insertSublayer(gradient, at: 0)
la source
Dans Swift 3.1, j'ai ajouté cette extension à UIView
que j'appelle ensuite avec
la source
J'ai implémenté cela dans mon code.
Maintenant, je peux voir un dégradé sur ma vue.
la source
Pour donner un dégradé de couleur à UIView (swift 4.2)
Comment utiliser
la source