Ich versuche zur Laufzeit eine Ansicht mit einem Farbverlaufshintergrund (einfarbig bis transparent) zu generieren. Gibt es eine Möglichkeit, das zu tun?
Ich versuche zur Laufzeit eine Ansicht mit einem Farbverlaufshintergrund (einfarbig bis transparent) zu generieren. Gibt es eine Möglichkeit, das zu tun?
Antworten:
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];
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)
Info : Verwenden Sie startPoint und endPoint, um die Richtung des Verlaufs zu ändern .
Wenn weitere Ansichten hinzugefügt werden UIView
(z. B. a UILabel
), sollten Sie die Hintergrundfarbe dieser Ansichten so einstellen UIView
, [UIColor clearColor]
dass die Verlaufsansicht anstelle der Hintergrundfarbe für Unteransichten angezeigt wird. Die Verwendung clearColor
hat einen leichten Leistungseinbruch.
view
auf self.view
und es funktionierte wie ein Zauber :)
gradient.frame = view.bounds
in viewDidAppear()
und in didRotateFromInterfaceOrientation()
würde die Steigung oder auch nicht richtig dimensioniert sein.
Sie können eine benutzerdefinierte Klasse erstellen GradientView
:
Swift 5
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]
}
}
Stellen Sie im Storyboard den Klassentyp auf eine Ansicht ein, für die Sie einen Verlaufshintergrund haben möchten:
Dies ist auf folgende Weise besser:
CLayer
NSConstraint
wie gewohnt auf demUIView
layerClass
ist das keine Funktion mehr, sondern eine Eigenschaft. Sie müssen es also wie eine Eigenschaft überschreiben : stackoverflow.com/questions/28786597/… . Außerdem müssen Sie implementieren override init(frame: CGRect)
, überprüfen Sie diese Antwort: stackoverflow.com/questions/27374330/... . Vielen Dank!
init(frame:CGRect)
. Ich habe den aktualisierten Code getestet und er funktioniert einwandfrei.
@IBDesignable
es verwendet wird?
Versuchen Sie dies, es hat wie ein Zauber für mich funktioniert,
Ziel c
Ich habe die Hintergrundfarbe für den RGB-Verlauf auf UIview eingestellt
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];
AKTUALISIERT: - Swift3 +
Code : -
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)
Sie können den Start- und Endpunkt der Verlaufsfarbe hinzufügen.
gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
Weitere Informationen finden Sie in CAGradientLayer Doc
Hoffe das ist Hilfe für jemanden.
Dies ist mein empfohlener Ansatz.
Um die Wiederverwendbarkeit zu fördern, würde ich sagen, erstellen Sie eine Kategorie von CAGradientLayer
und fügen Sie Ihre gewünschten Verläufe als Klassenmethoden hinzu. Geben Sie sie in der header
Datei wie folgt an :
#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
Geben Sie dann in Ihrer Implementierungsdatei jeden Farbverlauf mit der folgenden Syntax an:
+ (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;
}
Importieren Sie diese Kategorie dann einfach in Ihre ViewController
oder eine andere erforderliche Kategorie subclass
und verwenden Sie sie wie folgt:
CAGradientLayer *backgroundLayer = [CAGradientLayer purpleGradientLayer];
backgroundLayer.frame = self.view.frame;
[self.view.layer insertSublayer:backgroundLayer atIndex:0];
viewDidLoad
viewDidLoad
, funktionierte es nicht, wenn die App im Querformat gestartet wurde. Meine Lösung bestand darin, den Rahmen der Hintergrundebene breiter als den view.frame zu machen, um andere Ausrichtungen auszugleichen.
Da ich in meiner App nur einen Verlaufstyp benötigte, habe ich eine Unterklasse von UIView erstellt und die Verlaufsebene bei der Initialisierung mit festen Farben vorkonfiguriert. Die Initialisierer von UIView rufen die configureGradientLayer- Methode auf, die den CAGradientLayer konfiguriert:
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
initGradientLayer
ähnelt einem Initialisierer. Ich denke nicht, dass es sehr gut geeignet ist.
Schnelle Implementierung:
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)
Ich habe die akzeptierte Antwort ein wenig erweitert, indem ich die Erweiterungsfunktion von Swift sowie eine Aufzählung verwendet habe.
Oh, und wenn Sie Storyboard wie ich verwenden, rufen Sie gradientBackground(from:to:direction:)
an viewDidLayoutSubviews()
oder später.
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)
}
}
Ich habe dies schnell mit einer Erweiterung implementiert:
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)
}
}
Nein, ich kann für jede Ansicht wie folgt einen Farbverlauf festlegen:
myImageView.addGradientWithColor(UIColor.blue)
Ein schneller Ansatz
Diese Antwort baut auf den obigen Antworten auf und bietet eine Implementierung, um das Problem zu lösen, dass der Gradient während der Drehung nicht richtig angewendet wird. Dieses Problem wird gelöst, indem die Verlaufsschicht in ein Quadrat geändert wird, sodass eine Drehung in alle Richtungen zu einem korrekten Verlauf führt. Die Funktionssignatur enthält ein Swift-Variadic-Argument, mit dem so viele CGColorRefs (CGColor) wie erforderlich übergeben werden können (siehe Beispielverwendung). Außerdem wird ein Beispiel als Swift-Erweiterung bereitgestellt, mit dem ein Verlauf auf jede UIView angewendet werden kann.
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)
}
Benutzen:
in viewDidLoad ...
override func viewDidLoad() {
super.viewDidLoad()
configureGradientBackground(UIColor.redColor().CGColor, UIColor.whiteColor().CGColor)
}
Implementierung der Erweiterung
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)
}
}
Anwendungsbeispiel für eine Erweiterung:
override func viewDidLoad() {
super.viewDidLoad()
self.view.layer.configureGradientBackground(UIColor.purpleColor().CGColor, UIColor.blueColor().CGColor, UIColor.whiteColor().CGColor)
}
Dies bedeutet, dass der Verlaufshintergrund jetzt auf jedes UIControl angewendet werden kann, da alle Steuerelemente UIViews (oder eine Unterklasse) sind und alle UIViews CALayers haben.
Swift 4
Implementierung der Erweiterung
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)
}
}
Anwendungsbeispiel für eine Erweiterung:
override func viewDidLoad() {
super.viewDidLoad()
self.view.layer.configureGradientBackground(UIColor.purple.cgColor, UIColor.blue.cgColor, UIColor.white.cgColor)
}
Was Sie suchen, ist CAGradientLayer
. Jeder UIView
hat eine Ebene - in diese Ebene können Sie Unterebenen hinzufügen, genauso wie Sie Unteransichten hinzufügen können. Ein bestimmter Typ ist der CAGradientLayer
, bei dem Sie ihm eine Reihe von Farben zum Abstufen geben.
Ein Beispiel ist dieser einfache Wrapper für eine Verlaufsansicht:
http://oleb.net/blog/2010/04/obgradientview-a-simple-uiview-wrapper-for-cagradientlayer/
Beachten Sie, dass Sie das QuartZCore-Framework einschließen müssen, um auf alle Layer-Teile einer UIView zugreifen zu können.
Swift 4:
Zeigt den Farbverlauf in IB korrekt an:
@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]
}
}
extension UIView {
func applyGradient(isVertical: Bool, colorArray: [UIColor]) {
if let sublayers = layer.sublayers {
sublayers.filter({ $0 is CAGradientLayer }).forEach({ $0.removeFromSuperlayer() })
}
let gradientLayer = CAGradientLayer()
gradientLayer.colors = colorArray.map({ $0.cgColor })
if isVertical {
//top to bottom
gradientLayer.locations = [0.0, 1.0]
} else {
//left to right
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)
}
}
VERWENDUNG
someView.applyGradient(isVertical: true, colorArray: [.green, .blue])
Einfache schnelle Ansicht basierend auf Yuchens Version
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)
}
}
Dann können Sie gradientLayer nach der Initialisierung wie folgt verwenden ...
someView.gradientLayer.colors = [UIColor.whiteColor().CGColor, UIColor.blackColor().CGColor]
Meine Lösung besteht darin, eine UIView
Unterklasse zu erstellen, auf CAGradientLayer
die als schreibgeschützte Eigenschaft zugegriffen werden kann. Auf diese Weise können Sie Ihren Verlauf nach Ihren Wünschen anpassen und müssen Layoutänderungen nicht selbst vornehmen. Implementierung der Unterklasse:
@interface GradientView : UIView
@property (nonatomic, readonly) CAGradientLayer *gradientLayer;
@end
@implementation GradientView
+ (Class)layerClass
{
return [CAGradientLayer class];
}
- (CAGradientLayer *)gradientLayer
{
return (CAGradientLayer *)self.layer;
}
@end
Verwendungszweck:
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);
Es ist eine gute Idee, die oben genannten Lösungen aufzurufen, um die Ebene auf dem zu aktualisieren
viewDidLayoutSubviews
um die Ansichten korrekt zu aktualisieren
SWIFT 3
So fügen Sie Ihrer Ansicht eine Verlaufsebene hinzu
Binden Sie Ihren Sichtausgang
@IBOutlet var YOURVIEW : UIView!
Definiere den CAGradientLayer ()
var gradient = CAGradientLayer()
Hier ist der Code, den Sie in Ihr viewDidLoad schreiben müssen
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)
In Swift 3.1 habe ich diese Erweiterung zu UIView hinzugefügt
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)
}
}
mit dem rufe ich dann an
class OverviewVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.gradientOfView(withColours: UIColor.red,UIColor.green, UIColor.blue)
}
}
Ich habe dies in meinem Code implementiert.
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];
Jetzt sehe ich einen Farbverlauf in meiner Ansicht.
So geben Sie UIView eine Verlaufsfarbe (schnell 4.2)
func makeGradientLayer(`for` object : UIView, startPoint : CGPoint, endPoint : CGPoint, gradientColors : [Any]) -> CAGradientLayer {
let gradient: CAGradientLayer = CAGradientLayer()
gradient.colors = gradientColors
gradient.locations = [0.0 , 1.0]
gradient.startPoint = startPoint
gradient.endPoint = endPoint
gradient.frame = CGRect(x: 0, y: 0, w: object.frame.size.width, h: object.frame.size.height)
return gradient
}
Wie benutzt man
let start : CGPoint = CGPoint(x: 0.0, y: 1.0)
let end : CGPoint = CGPoint(x: 1.0, y: 1.0)
let gradient: CAGradientLayer = makeGradientLayer(for: cell, startPoint: start, endPoint: end, gradientColors: [
UIColor(red:0.92, green:0.07, blue:0.4, alpha:1).cgColor,
UIColor(red:0.93, green:0.11, blue:0.14, alpha:1).cgColor
])
self.vwTemp.layer.insertSublayer(gradient, at: 0)