No Shadow / Emboss on UIBarButtonItem

I have a problem with a custom UIBarButtonItem. When I create a custom UIBarButtonItem through

[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"FilterIcon.png"] style:UIBarButtonItemStyleBordered target:self action:@selector(filterTouched:)]; 

the resulting button does not have an “embossed” look that the elements of the system reach by placing a translucent black shadow behind its icons.

Left: system item, right: custom item

On the left you will see the "Organize" button element of the system panel, to the right of the code above.

Creating a shadow in a resource is useless since iOS / Cocoa only uses an image mask and discards any color information.

Interestingly, if I create a panel button element in Interface-Builder, it looks fine. However, in the context of my problem, I need to create a button element in the code.

+6
source share
3 answers

There is a version of the Objective-C James Furey script.

 - (UIImage *)applyToolbarButtonStyling:(UIImage *)oldImage { float shadowOffset = 1; float shadowOpacity = .54; CGRect imageRect = CGRectMake(0, 0, oldImage.size.width, oldImage.size.height); CGRect shadowRect = CGRectMake(0, shadowOffset, oldImage.size.width, oldImage.size.height); CGRect newRect = CGRectUnion(imageRect, shadowRect); UIGraphicsBeginImageContextWithOptions(newRect.size, NO, oldImage.scale); CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextScaleCTM(ctx, 1, -1); CGContextTranslateCTM(ctx, 0, -(newRect.size.height)); CGContextSaveGState(ctx); CGContextClipToMask(ctx, shadowRect, oldImage.CGImage); CGContextSetFillColorWithColor(ctx, [UIColor colorWithWhite:0 alpha:shadowOpacity].CGColor); CGContextFillRect(ctx, shadowRect); CGContextRestoreGState(ctx); CGContextClipToMask(ctx, imageRect, oldImage.CGImage); CGContextSetFillColorWithColor(ctx, [UIColor colorWithWhite:1 alpha:1].CGColor); CGContextFillRect(ctx, imageRect); UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 
+10
source

I think the reason this happens is covered by these answers to another question:

fooobar.com/questions/743391 / ...

fooobar.com/questions/743391 / ...

UIBarButtonItems behave differently depending on where you attach them programmatically. If you attach them to the toolbar, they will become white “embossed” icons. If you attach them to the navigation bar, they will not.

I spent the last few hours writing a function to apply the toolbar UIBarButtonItem style to UIImages. It is written in C # for MonoTouch , but I'm sure you can configure it on Obj-C without any problems ...

 UIImage ApplyToolbarButtonStyling(UIImage oldImage) { float shadowOffset = 1f; float shadowOpacity = .54f; RectangleF imageRect = new RectangleF(PointF.Empty, oldImage.Size); RectangleF shadowRect = new RectangleF(new PointF(0, shadowOffset), oldImage.Size); RectangleF newRect = RectangleF.Union(imageRect, shadowRect); UIGraphics.BeginImageContextWithOptions(newRect.Size, false, oldImage.CurrentScale); CGContext ctxt = UIGraphics.GetCurrentContext(); ctxt.ScaleCTM(1f, -1f); ctxt.TranslateCTM(0, -newRect.Size.Height); ctxt.SaveState(); ctxt.ClipToMask(shadowRect, oldImage.CGImage); ctxt.SetFillColor(UIColor.FromWhiteAlpha(0f, shadowOpacity).CGColor); ctxt.FillRect(shadowRect); ctxt.RestoreState(); ctxt.ClipToMask(imageRect, oldImage.CGImage); ctxt.SetFillColor(UIColor.FromWhiteAlpha(1f, 1f).CGColor); ctxt.FillRect(imageRect); UIImage newImage = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); return newImage; } 

So, UIBarButtonItem, which looked like this:

Before

Created using the function above, for example:

 UIBarButtonItem barButtonItem = new UIBarButtonItem(ApplyToolbarButtonStyling(UIImage.FromFile("MusicIcon.png")), UIBarButtonItemStyle.Plain, delegate {}); 

Now it will look like this:

After

Hope this helps someone in the future.

+7
source

Notice the shadow offset in the James Furey script. I did the following experiment:

 float shadowOffset = 1.0f // for a UIBarButtonItem in UINavigationItem float shadowOffset = 0.0f // for a UIBarButtonItem in UIToolBar 

This has been observed with the iOS 6.1 SDK.

(now deprecated under iOS 7)

0
source

Source: https://habr.com/ru/post/918362/


All Articles