Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do a set an opaque 1px high shadow image for a UINavigationBar?

In my application delegate's didFinishLaunchingWithOptions function, I try to customize the appearance of my navigation bar.

[UINavigationBar appearance].translucent = NO;
[[UINavigationBar appearance] 
    setBackgroundImage:[UIImage 
        imageWithColor:[UIColor whiteColor] 
        size:CGSizeMake(1.0f, 1.0f)
    ] 
    forBarMetrics:UIBarMetricsDefault
];
[UINavigationBar appearance].shadowImage = [UIImage 
    imageWithColor:[UIColor redColor] 
    size:CGSizeMake(0.5f, 0.5f)
];

I expect a 1px tall opaque red shadow. Instead I am given a 2px tall translucent red shadow. How can make it appear exactly as I want it to? I've done the analogous appearance settings to UITabBar. It, on the other hand, behaves nicely.

enter image description here

The category function that creates dynamic images is defined as so:

+ (UIImage*)imageWithColor:(UIColor *)color size:(CGSize)size
{
    CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}
like image 708
Pwner Avatar asked Dec 02 '14 20:12

Pwner


1 Answers

You need to create a graphics context that is retina-aware :

let pixelScale = UIGraphicsBeginImageContextWithOptions(fillRect.size, false, UIScreen.main.scale)

After that, your shadow image will become 1 physical pixel tall.

Here's full code:

extension UIImage {

    static func imageWithColor(color: UIColor) -> UIImage {
        let pixelScale = UIScreen.main.scale
        let pixelSize = 1 / pixelScale
        let fillSize = CGSize(width: pixelSize, height: pixelSize)
        let fillRect = CGRect(origin: CGPoint.zero, size: fillSize)
        UIGraphicsBeginImageContextWithOptions(fillRect.size, false, pixelScale)
        let graphicsContext = UIGraphicsGetCurrentContext()
        CGContextSetFillColorWithColor(graphicsContext, color.CGColor)
        CGContextFillRect(graphicsContext, fillRect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }

}

On GitHub:

https://github.com/salutis/swift-image-with-color

like image 64
Rudolf Adamkovič Avatar answered Oct 26 '22 12:10

Rudolf Adamkovič