wake-up-neo.com

Erstellen Sie programmgesteuert eine UIView mit Farbverlauf

Ich versuche, zur Laufzeit eine Ansicht mit einem Farbverlaufshintergrund (Einfarbig zu Transparent) zu erzeugen. Gibt es eine Möglichkeit, dies zu tun?

254
Allan Jiang

Ziel c:

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];

Schnell:

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 für Richtung des Verlaufs ändern .

Wenn dieser UIView weitere Ansichten hinzugefügt werden (z. B. eine UILabel), sollten Sie die Hintergrundfarbe dieser UIView auf [UIColor clearColor] setzen, sodass die Farbverlaufsansicht anstelle der Hintergrundfarbe für Unteransichten angezeigt wird. Die Verwendung von clearColor hat einen geringfügigen Performance-Treffer.

637
Arslan Ali

Sie können eine benutzerdefinierte Klasse GradientView erstellen: 

Swift 4, Swift 3

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]
    }
}

Legen Sie im Storyboard den Klassentyp auf jede Ansicht fest, die einen Hintergrund mit Farbverlauf haben soll: 

 enter image description here

Dies ist auf folgende Weise besser: 

  • Kein Rahmen für CLayer gesetzt
  • Verwenden Sie NSConstraint wie üblich für die UIView
  • Sie müssen keine Unterebenen erstellen (weniger Speicherverbrauch)
40
Yuchen Zhong

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 die gewünschten Gradienten als Klassenmethoden hinzu. Geben Sie sie in der Datei header folgendermaßen 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 folgender 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;
}

Dann importieren Sie diese Kategorie einfach in Ihre ViewController oder eine andere erforderliche subclass und verwenden Sie sie wie folgt:

CAGradientLayer *backgroundLayer = [CAGradientLayer purpleGradientLayer];
backgroundLayer.frame = self.view.frame;
[self.view.layer insertSublayer:backgroundLayer atIndex:0];
34
Sam Fischer

Versuchen Sie, dies funktionierte für mich wie ein Zauber,

Ziel c

Ich habe RGB Hintergrundfarbe des Farbverlaufs auf UIview gesetzt.

   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];

 enter image description here

AKTUALISIERTE :-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)

 enter image description here

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)

 enter image description here

Weitere Details finden Sie unter CAGradientLayer Doc

Hoffe, das ist eine Hilfe für jemanden.

29
Jaywant Khedkar

Da ich in meiner App nur eine Art von Verlauf brauchte, habe ich eine Unterklasse von UIView erstellt und die Verlaufsebene bei der Initialisierung mit festen Farben vorkonfiguriert. Die Initialisierer von UIView rufen die Methode configureGradientLayer- auf, die die Konfiguration vornimmt CAGradientLayer:

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
20
blauzahn

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)
12
Siva Visakan

Ich habe dies in Swift 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 in jeder Ansicht einen Farbverlauf so einstellen:

myImageView.addGradientWithColor(UIColor.blue)
8
patrickS

Ich habe die akzeptierte Antwort mit der Erweiterungsfunktion von Swift sowie einer Aufzählung ein wenig erweitert.

Oh, und wenn Sie Storyboard wie ich verwenden, müssen Sie unbedingt gradientBackground(from:to:direction:) in viewDidLayoutSubviews() oder später aufrufen.

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)
    }
}
8
arm0nic

Ein schneller Ansatz

Diese Antwort baut auf den obigen Antworten auf und bietet eine Implementierung für das Problem, dass der Gradient während der Rotation nicht ordnungsgemäß angewendet wird. Dieses Problem wird dadurch gelöst, dass die Gradientenschicht in ein Quadrat geändert wird, so dass die Drehung in alle Richtungen zu einem korrekten Gradienten führt. Die Funktionssignatur enthält ein variables Swift-Argument, mit dem beliebig viele CGColorRefs (CGColor) übergeben werden können (siehe Verwendungsbeispiel). Außerdem wird ein Beispiel als Swift-Erweiterung bereitgestellt, damit jeder UIView einen Verlauf zugewiesen 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)
  }

Erweiterungsimplementierung

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)
    }

}

Beispiel für Erweiterungsfälle:

 override func viewDidLoad() {
        super.viewDidLoad()

        self.view.layer.configureGradientBackground(UIColor.purpleColor().CGColor, UIColor.blueColor().CGColor, UIColor.whiteColor().CGColor)
 }

Das bedeutet, dass der Hintergrund mit Farbverlauf jetzt auf jedes UIControl-Element angewendet werden kann, da alle Steuerelemente UIViews (oder eine Unterklasse) sind und alle UIViews über CALayers verfügen.

Swift 4

Erweiterungsimplementierung

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 Erweiterungen:

override func viewDidLoad() {
    super.viewDidLoad()

    self.view.layer.configureGradientBackground(UIColor.purple.cgColor, UIColor.blue.cgColor, UIColor.white.cgColor)
}
6
Tommie C.

Was Sie suchen, ist CAGradientLayer. Jede 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 die CAGradientLayer, bei der Sie ein Farbfeld angeben, zwischen dem Sie einen Farbverlauf vornehmen können.

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 Ebenenteile einer UIView zugreifen zu können.

Einfache, schnelle Ansicht basierend auf der Version von Yuchen

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]
3
GregP

Meine Lösung ist das Erstellen einer UIView-Unterklasse, wobei CAGradientLayer als Readonly-Eigenschaft zugänglich ist. Auf diese Weise können Sie den Verlauf nach Ihren Wünschen anpassen und Layoutänderungen müssen nicht selbst vorgenommen werden. 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);
3

Es ist eine gute Idee, die oben genannten Lösungen aufzurufen, um die Schicht auf der 

viewDidLayoutSubviews 

um die Ansichten korrekt zu aktualisieren

3

Swift 4:

Zeigt die Steigung 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]
    }
}
3

Swift

m Ihrer Ansicht eine Verlaufsebene hinzuzufügen

  • Binden Sie Ihre Ansicht Steckdose

    @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)

2

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)
    }
}

was ich dann mit anrufe

    class OverviewVC: UIViewController {

        override func viewDidLoad() {
            super.viewDidLoad()

            self.view.gradientOfView(withColours: UIColor.red,UIColor.green, UIColor.blue)

        }
}
1
iCyberPaul

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 kann ich einen Verlauf in meiner Ansicht sehen.

0
Padmaja
extension UIView {

    func applyGradient(isTopBottom: Bool, colorArray: [UIColor]) {
        if let sublayers = layer.sublayers {
            let _ = sublayers.filter({ $0 is CAGradientLayer }).map({ $0.removeFromSuperlayer() })
        }

        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = colorArray.map({ $0.cgColor })
        if isTopBottom {
            gradientLayer.locations = [0.0, 1.0]
        } else {
            //leftRight
            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)
    }

}

VERWENDUNGSZWECK

someView.applyGradient(isTopBottom: true, colorArray: [.green, .blue])
0
Harris

Um UIView (Swift 4.2) eine Verlaufsfarbe zu geben

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)
0
Hardik Thakkar