webentwicklung-frage-antwort-db.com.de

Wie kann ich die UINavigationsleiste mit Farbverlauf einstellen?

Ich möchte UINavigationbarbackgroundColor auf eine Farbverlaufsfarbe setzen, wo ich sie über ein Array von Farben festlegen möchte, um einen Farbverlauf zu erstellen, idealerweise als zugängliche Methoden in UINavigationBar, um seine Farbe in diesen Farbverlauf zu ändern.

Irgendwelche Vorschläge? (Abgesehen von der manuellen Einstellung eines Bildes als Hintergrundbild der Navigationsleiste)

30
Ghanshyam Tomar

Erstellen Sie eine Verlaufsebene und fügen Sie sie als Hintergrund der Navigationsleiste hinzu.

    CAGradientLayer *gradient = [CAGradientLayer layer];
    gradient.frame = self.navigationController.navigationBar.bounds;
    gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor], (id)[[UIColor blackColor] CGColor], nil];
    [self.navigationController.navigationBar setBackgroundImage:[self imageFromLayer:gradient] forBarMetrics:UIBarMetricsDefault];

Zum Erstellen eines Bildes aus einer Ebene.

- (UIImage *)imageFromLayer:(CALayer *)layer
{
    UIGraphicsBeginImageContext([layer frame].size);

    [layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return outputImage;
}

In github gibt es noch eine Bibliothek: CRGradientNavigationBar Sie können diese Bibliothek auch verwenden.

24
Ashish Kakkad

Einzelheiten

Xcode 8.3.1, Swift 3.1

Code

erweiterung CAGradientLayer

extension CAGradientLayer {

    convenience init(frame: CGRect, colors: [UIColor]) {
        self.init()
        self.frame = frame
        self.colors = []
        for color in colors {
            self.colors?.append(color.cgColor)
        }
        startPoint = CGPoint(x: 0, y: 0)
        endPoint = CGPoint(x: 0, y: 1)
    }

    func createGradientImage() -> UIImage? {

        var image: UIImage? = nil
        UIGraphicsBeginImageContext(bounds.size)
        if let context = UIGraphicsGetCurrentContext() {
            render(in: context)
            image = UIGraphicsGetImageFromCurrentImageContext()
        }
        UIGraphicsEndImageContext()
        return image
    }

}

erweiterung UINavigationBar

extension UINavigationBar {

    func setGradientBackground(colors: [UIColor]) {

        var updatedFrame = bounds
        updatedFrame.size.height += self.frame.Origin.y
        let gradientLayer = CAGradientLayer(frame: updatedFrame, colors: colors)

        setBackgroundImage(gradientLayer.createGradientImage(), for: UIBarMetrics.default)
    }
}

Verwendungszweck

klasse ViewController

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var colors = [UIColor]()
        colors.append(UIColor(red: 221/255, green: 34/255, blue: 13/255, alpha: 1))
        colors.append(UIColor(red: 247/255, green: 113/255, blue: 98/255, alpha: 1))
        navigationController?.navigationBar.setGradientBackground(colors: colors)
    }
}

Hauptplatine

 enter image description here

Ergebnis

 enter image description here

56

In Swift 3 und Swift 4 :

let gradient = CAGradientLayer()
let sizeLength = UIScreen.main.bounds.size.height * 2
let defaultNavigationBarFrame = CGRect(x: 0, y: 0, width: sizeLength, height: 64)

gradient.frame = defaultNavigationBarFrame

gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor]

UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), for: .default)

So erstellen Sie ein Bild aus einer Ebene:

func image(fromLayer layer: CALayer) -> UIImage {
    UIGraphicsBeginImageContext(layer.frame.size)

    layer.render(in: UIGraphicsGetCurrentContext()!)

    let outputImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    return outputImage!
}

In Swift 2 :

let gradient = CAGradientLayer()
let sizeLength = UIScreen.mainScreen().bounds.size.height * 2
let defaultNavigationBarFrame = CGRectMake(0, 0, sizeLength, 64)

gradient.frame = defaultNavigationBarFrame

gradient.colors = [UIColor.whiteColor().CGColor, UIColor.blackColor().CGColor]

UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), forBarMetrics: .Default)

So erstellen Sie ein Bild aus einer Ebene:

func image(fromLayer layer: CALayer) -> UIImage {    
    UIGraphicsBeginImageContext(layer.frame.size)

    layer.renderInContext(UIGraphicsGetCurrentContext()!)

    let outputImage = UIGraphicsGetImageFromCurrentImageContext()

     UIGraphicsEndImageContext()

    return outputImage!
}
18
pableiros

Dies ist die Lösung, ohne eine Zwischenvariable CAGradientLayer und nur CoreGraphics in Swift 3.0 zu verwenden.

Im Wesentlichen erstellt die Methode im Handumdrehen eine UIImage mit den übergebenen Farbverläufen und legt sie fest.

extension UINavigationBar
{
    /// Applies a background gradient with the given colors
    func apply(gradient colors : [UIColor]) {
        var frameAndStatusBar: CGRect = self.bounds
        frameAndStatusBar.size.height += 20 // add 20 to account for the status bar

        setBackgroundImage(UINavigationBar.gradient(size: frameAndStatusBar.size, colors: colors), for: .default)
    }

    /// Creates a gradient image with the given settings
    static func gradient(size : CGSize, colors : [UIColor]) -> UIImage?
    {
        // Turn the colors into CGColors
        let cgcolors = colors.map { $0.cgColor }

        // Begin the graphics context
        UIGraphicsBeginImageContextWithOptions(size, true, 0.0)

        // If no context was retrieved, then it failed
        guard let context = UIGraphicsGetCurrentContext() else { return nil }

        // From now on, the context gets ended if any return happens
        defer { UIGraphicsEndImageContext() }

        // Create the Coregraphics gradient
        var locations : [CGFloat] = [0.0, 1.0]
        guard let gradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: cgcolors as NSArray as CFArray, locations: &locations) else { return nil }

        // Draw the gradient
        context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: size.width, y: 0.0), options: [])

        // Generate the image (the defer takes care of closing the context)
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

Die defer-Anweisung macht dies viel sauberer als in früheren Versionen . Beachten Sie, dass CGGradient seit iOS 8.0 verfügbar ist.

Dadurch wird auch der Verlauf von links nach rechts erstellt. Durch Ändern der Parameter von drawLinearGradient (start und end) werden die Positionen verschoben. Dies ist für Ihre Implementierung vorgesehen.

10
Can

Für Swift 4.2

extension UINavigationBar {
    func setGradientBackground(colors: [Any]) {
        let gradient: CAGradientLayer = CAGradientLayer()
        gradient.locations = [0.0 , 0.5, 1.0]
        gradient.startPoint = CGPoint(x: 0.0, y: 1.0)
        gradient.endPoint = CGPoint(x: 1.0, y: 1.0)

        var updatedFrame = self.bounds
        updatedFrame.size.height += self.frame.Origin.y
        gradient.frame = updatedFrame
        gradient.colors = colors;
        self.setBackgroundImage(self.image(fromLayer: gradient), for: .default)
    }

    func image(fromLayer layer: CALayer) -> UIImage {
        UIGraphicsBeginImageContext(layer.frame.size)
        layer.render(in: UIGraphicsGetCurrentContext()!)
        let outputImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return outputImage!
    }
}

Wie benutzt man

   self.navigationController?.navigationBar.setGradientBackground(colors: [
            UIColor.red.cgColor,
            UIColor.green.cgColor,
            UIColor.blue.cgColor
            ])
5
Hardik Thakkar

Swift 5

  • Schließt Statuszeile in Steigung ein.
  • Verwendet kein Bild.
  • Verwendet Transparenz, damit der Inhalt in der Navigationsleiste angezeigt wird.
extension UINavigationBar {

    func addGradient(_ toAlpha: CGFloat, _ color: UIColor) {
        let gradient = CAGradientLayer()
        gradient.colors = [
            color.withAlphaComponent(toAlpha).cgColor,
            color.withAlphaComponent(toAlpha).cgColor,
            color.withAlphaComponent(0).cgColor
        ]
        gradient.locations = [0, 0.8, 1]
        var frame = bounds
        frame.size.height += UIApplication.shared.statusBarFrame.size.height
        frame.Origin.y -= UIApplication.shared.statusBarFrame.size.height
        gradient.frame = frame
        layer.insertSublayer(gradient, at: 1)
    }

}
4
Jimmy_m

In Swift 3

let gradient = CAGradientLayer()
let sizeLength = UIScreen.main.bounds.size.height * 2
let defaultNavigationBarFrame = CGRect(x: 0, y: 0, width: sizeLength, height: 64)
gradient.frame = defaultNavigationBarFrame
gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), for: .default)

func image(fromLayer layer: CALayer) -> UIImage {
    UIGraphicsBeginImageContext(layer.frame.size)
    layer.render(in: UIGraphicsGetCurrentContext()!)
    let outputImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return outputImage!
}
4
Niklas

Swift 5

Um den horizontalen Verlaufshintergrund der Navigationsleiste zusammen mit der Statusleiste zu erstellen, geben Sie diesen Code einfach in die viewDidLoad() -Methode Ihres Viewcontrollers ein.

    self.navigationItem.title = "Gradiant Back Ground"
    let gradientLayer = CAGradientLayer()
    var updatedFrame = self.navigationController!.navigationBar.bounds
    updatedFrame.size.height += UIApplication.shared.statusBarFrame.size.height
    gradientLayer.frame = updatedFrame
    gradientLayer.colors = [UIColor.green.cgColor, UIColor.blue.cgColor] // start color and end color
    gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0) // Horizontal gradient start
    gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0) // Horizontal gradient end
    UIGraphicsBeginImageContext(gradientLayer.bounds.size)
    gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    self.navigationController!.navigationBar.setBackgroundImage(image, for: UIBarMetrics.default)

Gradient will look like this

der Ausgabegradient sieht dann so aus.

PROST!

1

Objective C-Lösung, die auch auf dem iPhone X funktioniert: 

- (void)addGradientToNavigationBar
{
    CAGradientLayer *gradient = [CAGradientLayer layer];
    CGRect gradientFrame = self.navigationController.navigationBar.bounds;
    gradientFrame.size.height += [UIApplication sharedApplication].statusBarFrame.size.height;
    gradient.frame = gradientFrame;
    gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorGradientUp] CGColor], (id)[[UIColor colorGradientDown] CGColor], nil];
    [self.navigationController.navigationBar setBackgroundImage:[self imageFromLayer:gradient] forBarMetrics:UIBarMetricsDefault];
}

- (UIImage *)imageFromLayer:(CALayer *)layer
{
    UIGraphicsBeginImageContext([layer frame].size);

    [layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return outputImage;
}
1
wzbozon

Dieses erstaunliche Tutorial von Lawrence Tan zeigt, wie man mit barTintColor und no backgroundImage einen Farbverlauf einstellt: https://medium.com/Swift2go/add-gradient-to-navigation -bar-in-Swift-9284fe91fea2

Zusammenfassung

CAGradientLayer Erweiterung

extension CAGradientLayer {

    class func primaryGradient(on view: UIView) -> UIImage? {
        let gradient = CAGradientLayer()
        let flareRed = UIColor(displayP3Red: 241.0/255.0, green: 39.0/255.0, blue: 17.0/255.0, alpha: 1.0)
        let flareOrange = UIColor(displayP3Red: 245.0/255.0, green: 175.0/255.0, blue: 25.0/255.0, alpha: 1.0)
        var bounds = view.bounds
        bounds.size.height += UIApplication.shared.statusBarFrame.size.height
        gradient.frame = bounds
        gradient.colors = [flareRed.cgColor, flareOrange.cgColor]
        gradient.startPoint = CGPoint(x: 0, y: 0)
        gradient.endPoint = CGPoint(x: 1, y: 0)
        return gradient.createGradientImage(on: view)
    }

    private func createGradientImage(on view: UIView) -> UIImage? {
        var gradientImage: UIImage?
        UIGraphicsBeginImageContext(view.frame.size)
        if let context = UIGraphicsGetCurrentContext() {
            render(in: context)
            gradientImage = UIGraphicsGetImageFromCurrentImageContext()?.resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch)
        }
        UIGraphicsEndImageContext()
        return gradientImage
    }
}

Wenden Sie den Farbverlauf an

guard
    let navigationController = navigationController,
    let flareGradientImage = CAGradientLayer.primaryGradient(on: navigationController.navigationBar)
    else {
        print("Error creating gradient color!")
        return
    }

navigationController.navigationBar.barTintColor = UIColor(patternImage: flareGradientImage)
0
Kévin Renella

Dies ist ein Framework für verschiedene UI-Komponenten. Der Farbverlauf umfasst die UINavigation-Leiste: Linkbeschreibung hier eingeben

erstens: dann in deinem root ViewController, dass er in einen UINavigationController eingebettet ist

import SHNDStuffs

fügen Sie dies in Ihr ViewDidLoad () ein

class RootViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        SHNDNavigationBarGradient(firstColor: .darkGray,
                                  secondColor: .white,
                                  tintColor: .black,
                                  isHorizontal: true)
}
0
shndrs