用CGGradientRef填充UINavigationBar背景

时间:2015-04-19 14:15:25

标签: ios uiimage uinavigationbar

我想用UINavigationBar填充CGGradientRef背景而不是图片文件(例如myBackground.png)。这种做法将避免为每个屏幕大小创建PNG文件,同时节省存储空间。

我已经看到可以创建UIImage从头开始绘制渐变并使用:

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

此外,我已经看到我可以使用以下内容将UIImage分配给UINavigationBar

myNavigationController.navigationBar.barTintColor = [UIColor colorWithPatternImage:image]];

但是,我还没把这两者放在一起。一些帮助将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:1)

以下是使用两点渐变的重载UINavigationBar类,尽管可以轻松改进以覆盖多点渐变。

要启用此栏样式,请在情节提要的导航场景中选择导航栏对象,并将其自定义类设置为GradientNavigationBar

在这种情况下,awakeFromNib调用用于更改背景(假设导航栏类已在故事板中更改),如果导航栏以编程方式实例化,则自定义调用应该在代码中的适当位置。

该解决方案的工作原理是将传递给它的颜色转换为CGFloat数组,然后使用这些颜色生成CGGradientRef对象,创建图像,然后使用setBackgroundImage:forBarMetrics调用根据需要设置背景。

@interface GradientNavigationBar

@end

@implementation GradientNavigationBar

-(void) awakeFromNib {
    [self setGradientBackground:[UIColor redColor] 
                       endColor:[UIColor yellowColor]];
}

-(void) setGradientBackground:(UIColor *) startColor endColor:(UIColor *) endColor {

    // Convert the colors into a format where they can be used with
    // core graphics

    CGFloat rs, gs, bs, as, re, ge, be, ae;
    [startColor getRed:&rs green:&gs blue:&bs alpha:&as];
    [endColor   getRed:&re green:&ge blue:&be alpha:&ae];
    CGFloat colors [] = {
        rs, gs, bs, as,
        re, ge, be, ae
    };

    // Generate an Image context with the appropriate options, it may
    // be enhanced to take into account that Navbar heights differ
    // eg between landscape and portrait in the iPhone
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
    CGContextRef gc = UIGraphicsGetCurrentContext();
    CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();

    // The gradient element indicates the colors to be used and 
    // the color space
    CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2);
    CGColorSpaceRelease(baseSpace), baseSpace = NULL;

    // Draw the gradient
    CGContextDrawLinearGradient(gc, gradient, CGPointMake(0, 0),CGPointMake(0, self.bounds.size.height),0);

    // Capture the image
    UIImage * backgroundImage = UIGraphicsGetImageFromCurrentImageContext();

    // The critical call for setting the background image
    // Note that separate calls can be made e.g. for the compact
    // bar metric.
    [self setBackgroundImage:backgroundImage  forBarMetrics:UIBarMetricsDefault];

    CGGradientRelease(gradient), gradient = NULL;
    UIGraphicsEndImageContext();


}
@end