color bar ios uinavigationbar core-graphics

ios - navigation bar title color



¿Cómo puedo configurar la barra de navegación UIN con color degradado? (11)

Quiero establecer el UINavigationbar backgroundColor la UINavigationbar en un color de degradado donde me gustaría establecerlo a través de una matriz de colores para crear un degradado, idealmente, como métodos accesibles dentro de UINavigationBar para cambiar su color a este degradado.

¿Alguna sugerencia? (Además de configurar una imagen manualmente como imagen de fondo de la barra de navegación)


Swift 5

  • Incluye barra de estado en gradiente.
  • No usa una imagen.
  • Utiliza la transparencia para que el contenido sea visible a través de la barra de navegación.

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


Detalles

  • Xcode 10.2 (10E125)
  • Swift 5

Código

extensión CAGradientLayer

import UIKit extension CAGradientLayer { enum Point { case topRight, topLeft case bottomRight, bottomLeft case custion(point: CGPoint) var point: CGPoint { switch self { case .topRight: return CGPoint(x: 1, y: 0) case .topLeft: return CGPoint(x: 0, y: 0) case .bottomRight: return CGPoint(x: 1, y: 1) case .bottomLeft: return CGPoint(x: 0, y: 1) case .custion(let point): return point } } } convenience init(frame: CGRect, colors: [UIColor], startPoint: CGPoint, endPoint: CGPoint) { self.init() self.frame = frame self.colors = colors.map { $0.cgColor } self.startPoint = startPoint self.endPoint = endPoint } convenience init(frame: CGRect, colors: [UIColor], startPoint: Point, endPoint: Point) { self.init(frame: frame, colors: colors, startPoint: startPoint.point, endPoint: endPoint.point) } func createGradientImage() -> UIImage? { defer { UIGraphicsEndImageContext() } UIGraphicsBeginImageContext(bounds.size) guard let context = UIGraphicsGetCurrentContext() else { return nil } render(in: context) return UIGraphicsGetImageFromCurrentImageContext() } }

extensión UINavigationBar

import UIKit extension UINavigationBar { func setGradientBackground(colors: [UIColor], startPoint: CAGradientLayer.Point = .topLeft, endPoint: CAGradientLayer.Point = .bottomLeft) { var updatedFrame = bounds updatedFrame.size.height += self.frame.origin.y let gradientLayer = CAGradientLayer(frame: updatedFrame, colors: colors, startPoint: startPoint, endPoint: endPoint) setBackgroundImage(gradientLayer.createGradientImage(), for: UIBarMetrics.default) } }

Uso

clase ViewController

import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let colors: [UIColor] = [.red, .white] navigationController?.navigationBar.setGradientBackground(colors: colors) //navigationController?.navigationBar.setGradientBackground(colors: colors, startPoint: .bottomLeft, endPoint: .topRight) } }

Main.storyboard

Resultado


Cree una capa de degradado y agréguela como fondo de la barra de navegación.

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

Para crear imagen a partir de capa.

- (UIImage *)imageFromLayer:(CALayer *)layer { UIGraphicsBeginImageContext([layer frame].size); [layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return outputImage; }

Una cosa más, hay una biblioteca disponible en github: CRGradientNavigationBar también puede usar esta biblioteca.


En Swift 3 y 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)

Para crear una imagen desde la capa:

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

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

Para crear una imagen desde la capa:

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


En 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! }


Esta es la solución sin usar un CAGradientLayer intermedio, y solo usando CoreGraphics , en Swift 3.0.

Esencialmente, el método crea un UIImage sobre la marcha con los colores degradados pasados ​​y lo establece.

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

La declaración de defer hace que esto sea mucho más limpio que las versiones anteriores. Tenga en cuenta que CGGradient está disponible desde iOS 8.0.

Además, esto crea el gradiente de izquierda a derecha, ajustando los parámetros de drawLinearGradient ( start y end ) mueve las ubicaciones. Esto depende de su implementación.


Este es un marco para diferentes componentes de la interfaz de usuario que incluyen la barra de navegación UIN: ingrese la descripción del enlace aquí

primero: luego en su ViewController raíz que se incrustó en un UINavigationController

import SHNDStuffs

poner esto en su ViewDidLoad ()

class RootViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() SHNDNavigationBarGradient(firstColor: .darkGray, secondColor: .white, tintColor: .black, isHorizontal: true) }


Este increíble tutorial de Lawrence Tan  muestra cómo establecer un degradado usando barTintColor y sin backgroundImage : https://medium.com/swift2go/add-gradient-to-navigation-bar-in-swift-9284fe91fea2

Resumen

Extensión CAGradientLayer

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

Aplicar el gradiente

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


Solución Objective C que también funciona en iPhone X:

- (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; }


Para 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! } }

Cómo utilizar

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


SWIFT 5

Para hacer el fondo degradado horizontal de la barra de navegación junto con la barra de estado también ... simplemente ponga este código en el método viewDidLoad() su controlador de viewDidLoad() .

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)

El gradiente de salida se verá así.

¡ACLAMACIONES!