solid guidelines color bar iphone cocoa-touch interface-builder

iphone - guidelines - set navigation bar swift



UINavigationBar tintColor con gradiente (5)

Me gustaría cambiar programáticamente el tintColor de una UINavigationBar y mantener el degradado como en Interface Builder.

Cuando cambio el tintColor en mi código, el degradado desaparece, pero cuando cambio el tintColor en el Interface Builder, el gradiente se mantiene.

¿Algunas ideas?


Establezca barStyle en UIBarStyleBlackTranslucent Establezca el tintColor de la siguiente manera:

navigationBar.tintColor = [UIColor colorWithRed:.7 green:.5 blue:.2 alpha:1];

Esto establecerá el gradiente apropiado. Usa la combinación que necesites.


navigation.tintColor = [UIColor colorWithRed:0.47f green:0.23f blue:0.61f alpha:1.0f];


Así que esta es una vieja pregunta, pero me encontré con ella cuando estaba buscando algo que suena como esta pregunta, pero es diferente. Con la esperanza de que ayude a alguien más (o que alguien más me muestre una mejor manera) ...

¿Cómo se implementa un degradado personalizado en un UINavigationBar?

Primero, obtengamos nuestro gradiente personalizado como lo haríamos normalmente (Como CALayer):

- (CALayer *)gradientBGLayerForBounds:(CGRect)bounds { CAGradientLayer * gradientBG = [CAGradientLayer layer]; gradientBG.frame = bounds; gradientBG.colors = @[ (id)[[UIColor redColor] CGColor], (id)[[UIColor purpleColor] CGColor] ]; return gradientBG; }

Ahí vamos, un degradado que parece una opción de maquillaje cuestionable de un punk rocker, que es bueno, ya que este código es para la aplicación hipotética Tengo un punk-rockero con gustos cuestionables en mi bolsillo . Ese nombre soy un poco demasiado largo ...

Ahora quiero esta capa en mi UINavigationBar, ¿qué debería ser fácil? Solo agrégalo como una subcapa, ¿verdad? El problema aquí es que cubrirá los maravillosos botones y cosas que el UINavigationController le brinda. Eso es malo.

En cambio, veamos el maravilloso método de conveniencia que tenemos en iOS5 + para alterar la apariencia de todos los UINavigationBar (s) en nuestra aplicación:

[[UINavigationBar appearance] setBackgroundImage:SOME_IMAGE forBarMetrics:UIBarMetricsDefault];

El único problema aquí es que no tenemos un UIImage, tenemos un CALayer. ¿Qué hace un entusiasta del punk-rocker?

CALayer * bgGradientLayer = [self gradientBGLayerForBounds:ONE_OF_YOUR_NAV_CONTROLLERS.navigationBar.bounds]; UIGraphicsBeginImageContext(bgGradientLayer.bounds.size); [bgGradientLayer renderInContext:UIGraphicsGetCurrentContext()]; UIImage * bgAsImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();

Así que ahora hemos convertido nuestro CALayer en un UIImage (con suerte), así que todo lo que queda es establecerlo:

if (bgAsImage != nil) { [[UINavigationBar appearance] setBackgroundImage:bgAsImage forBarMetrics:UIBarMetricsDefault]; } else { NSLog(@"Failded to create gradient bg image, user will see standard tint color gradient."); }

Lo que me gusta de esta solución es

  • el código centralizado (en el AppDelegate) para todos los UINavigationBar (s) en mi aplicación
  • tintColor seguirá siendo respetado para todos los botones de UINavigation (retroceder, editar, etc.)
  • si la creación de UIImage falla, mi UINavigationBar (s) aún honrará el tintColor
  • No tengo que depender de un recurso de imagen real / fácil de actualizar

Pero todavía no estoy convencido de que sea la mejor manera. Entonces, disfruta si te ayuda, házmelo saber cómo mejorarlo si puedes.

~ Gracias


Lo escribí como extensión UIImage para Swift 2.0. Tal vez sea de alguna utilidad.

extension UIImage { class func convertGradientToImage(colors: [UIColor], frame: CGRect) -> UIImage { // start with a CAGradientLayer let gradientLayer = CAGradientLayer() gradientLayer.frame = frame // add colors as CGCologRef to a new array and calculate the distances var colorsRef : [CGColorRef] = [] var locations : [NSNumber] = [] for i in 0 ... colors.count-1 { colorsRef.append(colors[i].CGColor as CGColorRef) locations.append(Float(i)/Float(colors.count)) } gradientLayer.colors = colorsRef gradientLayer.locations = locations // now build a UIImage from the gradient UIGraphicsBeginImageContext(gradientLayer.bounds.size) gradientLayer.renderInContext(UIGraphicsGetCurrentContext()!) let gradientImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() // return the gradient image return gradientImage } }

Llámalo así:

let colors = [ UIColor.blueColor(), UIColor.greenColor() // and many more if you wish ] let gradientImage = UIImage.convertGradientToImage(colors, frame: navigationBar.bounds) navigationBar.setBackgroundImage(gradientImage, forBarMetrics: .Default)


Buena forma de usar maskView

// create gradient view let gradientView: UIView = UIView(frame: frame) let gradient: CAGradientLayer = CAGradientLayer() gradient.frame = gradientView.bounds gradient.colors = [UIColor.grayColor().CGColor, UIColor.clearColor().CGColor] gradientView.layer.insertSublayer(gradient, atIndex: 0) //set appearance UINavigationBar.appearance().maskView = gradientView