6

I've had trouble getting this to work, nowhere have I seen a working example on the web. Now offering bounty on this as its making me crazy. It should be easy, but that doesn't seem to be the case.

I'd like my buttons on my UINavigationBar to be semi-transparent such that they allow the background of whatever is on the UINavigationBar to show through. This effect is seen in many applications, image examples below. You can do this by setting a custom background on the item, which i think is an unacceptable solution because it requires that you prepare images beforehand, and they won't be adaptable for variable buttons etc. They will not look like Apple UI and I don't believe there is a reason to do this either, UIKit is already drawing the background for these buttons, we just need to change it. The correct solution uses the bar items and views generated by Apple's apis.

UIBarButtonItem is not a UIView subclass. When you create one and add it to a UINavigationBar, some code somewhere in the framework draws a view for it. The framework methods seem to resist anything related to allowing transparency of the bar items, such as the tintColor property.

For example, this does NOT work:

 UINavigationItem *item = [[UINavigationItem alloc] init];
 UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:@"SUCKS" style:UIBarButtonItemStyleBordered target:self action:@selector(whatever:)];
editButton.tintColor = [UIColor colorWithWhite:0.4 alpha:0.3];
item.leftBarButtonItem = editButton;

Nothing I do will make UINavigationBar allow semi-transparency for its bar items. I believe at runtime we need to:

  1. Get the image for the bar item
  2. Mask it for transparency
  3. Set the new image on the bar item

But I haven't been able to get the image at runtime or mask it properly. How do you do this?

Like This

Community
  • 1
  • 1
Lana Miller
  • 1,141
  • 2
  • 12
  • 22

5 Answers5

5

Create a custom uiview and draw a semi-transparent black rectangle in it and use that view with initWithCustomView.

see and

Failing that, you may have to use an image (png). e.g. a 1x1 black pixel png with 30% opacity.You could then initWithImage.

EDIT: I have had this second approach working using:

buttonThree = [[UIBarButtonItem alloc] initWithTitle:@" sort button " style:UIBarButtonItemStyleBordered target:self action:@selector(sortMethod)];
UIImage *thebgUIimage = [UIImage imageNamed:@"semi.png"];
[buttonThree setBackgroundImage:thebgUIimage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

This results in a button that has a transparent background image that the navbar background image shows through. However, you would need to create an image with the rounded corners on and so need an image for each button width. Also I found this thread after trying the above

Community
  • 1
  • 1
ader
  • 5,403
  • 1
  • 21
  • 26
  • I'm investigating your suggestions, I don't know too much about Core Graphics but the libraries seem low level and basic: IE not powerful unless you know how to use them IE: TONS of reading, practice and learning required. In the example image, it looks like the effect could be achieved with a rounded view, semi opaque, but also requires a border be traced around the shape. – Lana Miller Jan 10 '12 at 04:37
  • Unless you have a working code sample, I think what you suggested about using a custom view filled with a semi-transparent rect...does not work. Alpha is ignored once the UIBarButtonItem with the custom view is added to a nav bar. – Lana Miller Jan 15 '12 at 15:24
  • 1
    @ade you can create a stretchable image with rounded corners and transparency, this would work for all button sizes. I think that is probably what is required here. – jrturton Jan 16 '12 at 19:26
  • I have a custom UIView on my UIBarButtonItem but making that view semi-transparent doesn't work. It seems to just ignore alpha on the Nav bar. – n13 Feb 21 '13 at 04:41
2

A brilliant hack is to use the UISegmentedControl with a single segment (as a button) and set its tint color. Have a look at http://charles.lescampeurs.org/2011/02/10/tint-color-uibutton-and-uibarbuttonitem. I have personally implemented this. Feel free to ask any questions.

Akshay
  • 5,747
  • 3
  • 23
  • 35
  • 1
    So does that give the desired effect if you tint it with a semitransparent colour? – jrturton Jan 19 '12 at 08:21
  • It does. The tintColor property is set perfectly. – Akshay Jan 20 '12 at 02:57
  • This doesn't work, it changes the tintColor but the alpha is ignored and there is no transparency when added to a navigation bar. You say the tintColor property is set, and sure you can change the colors, but alpha is the goal here. – Lana Miller Jan 22 '12 at 14:40
  • Did you try `+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha` ? – Akshay Jan 23 '12 at 06:53
0

Instead of searching for code and breaking your head, my suggestion is just to have transparent image which has just border similar to button (add shadow if necessary), create a button of custom type, add the transparent background image to it and you can text as you want. From this custom button, create your bar button item accordingly.

Satyam
  • 15,493
  • 31
  • 131
  • 244
  • Hey thanks. Beyond searching for sample code, I've tried to implement it myself using any methods or properties in the documentation that seemed relevant. The approach you suggest can work to create a button, but it won't look pixel perfect if you are generating your own button backgrounds, it needs to look like apple UI. – Lana Miller Jan 16 '12 at 03:17
  • No, for creating bar button item, it has a method to use custom view as bar button item. so you just have to create an image that you want to use as bar button item. that's it. – Satyam Jan 16 '12 at 05:37
0

If you're targeting for iOS 5, you can set the background image of the button.

    [_button setBackgroundImage:@"image" forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

Note that you'll need to set background images for state UIControlSateSelected and again for both control states for barMetrics: UIBarMetricsLandscape, if your application allows landscape orientation.

Note again this is an iOS 5 feature.

Aaron Hayman
  • 8,492
  • 2
  • 36
  • 63
  • From the wording of the original question, this does not seem to be the "right" approach as it will involve preparing a "custom" image background. Personally, I would actual use this solution instead, but hey, the OP seems to know better and *wants* a more generic solution. – Till Jan 15 '12 at 17:13
  • Yeah, fair enough. I figured if he didn't know about this solution it might be useful. – Aaron Hayman Jan 15 '12 at 17:16
  • Hey guys, thanks for the responses. This is a good approach, but the image to set is the problem here. Photoshopping some button background to look kinda right is no good, it will look non-apple and amateur. I may not have said it clearly in the OP, but what really seems to be the right approach here is to GET the image from the Apple-generated bar item, and mask it somehow so that it contains transparency, then re-set it on the item and possibly make sure anything related to opaque=NO or other transparency related options are set correctly. – Lana Miller Jan 16 '12 at 03:21
0

I believe your answer is here: http://sebastiancelis.com/2009/12/21/adding-background-image-uinavigationbar/

Adem Özgür
  • 200
  • 1
  • 10
  • That is an article on method swizzling to get a background image on UINavigationBar. Can swizzling be used to call code in undocumented classes without being denied on submission to Apple? I doubt it, but if so, its possible this could work. – Lana Miller Jan 22 '12 at 14:48
  • yes, i submitted an app with this code and it is now on app store ;) – Adem Özgür Apr 17 '12 at 15:04