Alter a UIBarButtonItem view to be transparent programmatically - iphone

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:
Get the image for the bar item
Mask it for transparency
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?

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

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.

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.

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.

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

Related

UIToolbar gradient fix

I am using UIToolbar in my project for this lock screen. Everything is fine except the gradient on the UIToolbar is very short. I mean its height is not equal. I have attached the screen shot. I want the UIToolbar to be like figure B.
Any idea how to achieve this.
Best thing you can do is setting appearance for your UIToolBar:
UIImage *gradientImage = [[UIImage imageNamed:#"upperBar.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(-4, 300, 10, 300)];
UIToolbar *toolbar = [UIToolBar appearance];
[toolbar setBackgroundImage:gradientImage forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
Where upperBar.png is the gradient image you want.
A UIToolbar in iOS6 and earlier always draws its shine over the top 22px. If you want a bigger shine, you'll have to provide a background image using setBackgroundImage:forToolbarPosition:barMetrics:.
Two more things, though:
UIToolbar on an iPhone expects to be at the bottom of your content; if you're using it to give you a background suitable for the top, you should use a UINavigationBar instead.
The appearance of toolbars, navigation bars, and the lock screen has changed in iOS7. You may want to rethink your approach so that your app doesn't look bad in the near future.

iOS5 Toolbar background image

I'm very new to iOS programming.
I'm trying to set the toolbar background to a custom image.
I'm also using storyboards.
How do I go about that?
Do I edit UIToolbar in the UI Kit framework? Do I need to change something in Storyboard?
Thanks,
You can use UIToolbar's built-in -setBackgroundImage:forToolbarPosition:barMetrics: method:
// portrait
[yourToolbar setBackgroundImage:[UIImage imageNamed:#"YourToolbarBkg-Portrait.png"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
// landscape
[yourToolbar setBackgroundImage:[UIImage imageNamed:#"YourToolbarBkg-Landscape.png"] forToolbarPosition:UIToolbarPositionAny barMetrics: UIBarMetricsLandscapePhone];
YourToolbarBkg-Portrait.png will be 320x44 bkg image for portrait mode
YourToolbarBkg-Landscape.png will be 480x32 bkg image for landscape mode.
UIToolbar inherits from UIView. This just worked for me:
[topBar insertSubview:[[[UIImageView alloc] initWithImage:[UIImage imageNamed:BAR_BKG_IMG]] autorelease] atIndex:0];
UPDATED
topBar ------ is the outlet of the UIToolBar u are using
use this code where u are creating ur UIToolBar the class which implements the UIToolbar..
plus tell me y r u using Toolbar whats ur main purpose for it
Instead of editing UIToolBar, why not create a UIView of the same size and skin that however you would like? That would be easier if you are new.
Or if you want to override UIToolbar:
#implementation UIToolbar (CustomImage)
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed: #"image.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
Had a right faff with background images for ToolBars and NavBars. I know setting the background image of a NavBar and ToolBar is generally a doddle. But, when you're presenting modal VC's, for some insane reason, where a NavBar is being added and you DO change the background image, it appears to double in size. Altering the height has strange results.
My issue was where I was using a NavController all over my App, but needed a modal view for one or two aspects of it. Simple enough. However, I needed either a NavBar or ToolBar type header with a Done button to pop the VC off the stack. Again, not an issue. But I needed the NavBar or ToolBar to look the same as everywhere else in my App.
I settled on a ToolBar, seeing as the VC was being presented modally. So, there my ToolBar sat, in typical Apple-blue. Nice, but not how the rest of my App looked, where a blackened image was being used for each NavBar. Using the iOS 5 appearance proxy, I altered the background image of the ToolBar. And this worked. But, unless I had the UIImage in exactly the proportions and size expected by the Tool Bar, I was in a pickle. The image simply did not look right at all. So, I decided to create a UIIMageView, where I could control the content mode, then insert a subview onto the toolBar.
Take a look at my code below.
UIImageView *toolbarImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:NAV_BAR_BACKGROUND]];
[toolbarImageView setFrame:[self.IBOToolBar bounds]];
[toolbarImageView setContentMode:UIViewContentModeScaleAspectFill];
[self.IBOToolBar insertSubview:toolbarImageView atIndex:1];
It's a bit of a fluff but I do hope this helps someone alter the image on their ToolBar.
NAV_BAR_BACKGROUND can be defined as follows:
#define NAV_BAR_BACKGROUND #"navBarBlackMattDarkSquare.png"

How to create a gray overlay for a UIButton in touched state programmatically?

I would like to make a generic class that when tapped, makes the element grayish.
Facebook's app is the perfect example of what I want to achieve. All their links and images become gray when tapped.
I can only guess that they are subclassing UIButton.
I have made my button's style UIButtonTypeCustom to get rid of the rounded border. Beyond this, I don't know how to have the gray overlay because I see no such property in the documentation.
Its simple:
#define TAG_GRAYVIEW 5671263 // some random number
// add the gray overlay
UIView *grayView = [[UIView alloc] initWithFrame:button.bounds];
grayView.backgroundColor = [UIColor grayColor];
grayView.tag = TAG_GRAYVIEW;
[button addSubview:grayView];
// remove the gray overlay
UIView *grayView = [button viewWithTag:TAG_GRAYVIEW];
[grayView removeFromSuperview];
I think you need to use a semi transperant grey image PNG file. You need to then set Image of button in Highlighted state.
Also note that both the images for Normal State and Highlighted State need to have the images with titles on them.
As once we set the image to button, btn.titleLabel.text won't be displayed.
So you can have a image with transperant background and title on it for Normal state. And an grey image with title on it for Highlighted State.
Code for doing it programmatically is
[btn setImage:#"Transperant.png" forState:UIControlStateNormal];
[btn setImage:#"Grey.png" forState:UIControlStateHighlighted];
Hope this helps you.
The default UIButton masks the opaque content using a gray highlight. For example when using a transparent png, only the parts that contain non-transparent pixels will be grayed out on touch. The default UIButton highlight has no effect on subviews/sublayers, and will only work on provided images. What you see in the Facebook app is probably just a UIWebView highlight, possibly customized using css.
To create something similar using your own control (to prevent the overhead of a UIWebView) you should probably create your own UIControl subclass and highlight the content on touch using a transparent CALayer. You can even mask the CALayer to only highlight the actual contents, instead of a rectangular shape.
Also see my stackoverflow post on creating custom controls for iOS by subclassing UIControl.
Try setting the button up something like this.
*mind you I didn't create the image for this example.
Set your button type to custom, and in "State Config" select "Highlighted" from there you will want to set the image of the button to be a semi-transparent grey image. There are probably several other ways to achieve this same effect but this one should be nice and simple.

UITabBar fully transparent

In XCode I am using the interface builder (StoryBoard) to lay out most of my layout. However I want some custom drawing on this. This works quite well.
There is however a problem what I am facing. I have a "bite" out of the active tab. (see http://cl.ly/Efno ) I want this bite fully transparent. (I have set an pink background color to see what part I want transparent which is not transparent.)
How I have changed the look and feel is the following.
Set the UITabBar class to my own class in the interface builder for the corresponding tabbar.
In the awakeFromNib of that class I have set the label position and image and selected image of each tabbar item. Like so
[tabBarItem setFinishedSelectedImage:selectedImage withFinishedUnselectedImage:image];
Each image fully covers the entire tabbar in height and has the width of the tab item itself.
Set the background image of the tabbar to none (a fully transparent image)
Set the background color of the tabbar to a fully transparent color (now I have a pink color set to see where it goes wrong)
In the interface builder uncheck "opaque" for the tabbar.
However, it is not transparent, the pink part is black. How can I make this transparent?
Thanks
Have a look at the appearance proxy for UITabBar, you might be able to do what you want there without having to use a custom subclass. There are tons of properties you can access and change. You could set the relevant properties in the app delegate. It is iOS5 only though, but I gather that you are using that already, since you mentioned storyboards.
E.g.
UIImage *tabBarBackground = [UIImage imageNamed:#"tabBarBackground.png"];
[[UITabBar appearance] setBackgroundImage:tabBarBackground];
[[UITabBar appearance] setSelectedImageTintColor:[UIColor colorWithRed:127.0/255.0 green:186.0/255.0 blue:235.0/255.0 alpha:1.0]];
[[UITabBar appearance] setSelectionIndicatorImage:[UIImage imageNamed:#"tabBarItemSelected.png"]];

UIBarButtonItem Highlighted Color

I have set a custom tint color for a UINavigationBar (within a UINavigationController) which, in turn, sets an appropriate matching color for the UIBarButtonItems which are inserted into the UINavigationBar. However, when I select a UIBarButtonItem the button turns into (presumably) the highlighted state and presents a different color, which looks quite a bit out and does not nicely match the tint color. Is there a way to change this highlighted state color to a custom color?
Ideally, I would like to just create a category on UIBarButtonItem which changes the highlighted color for all instances of UIBarButtonItem, as this would avoid the need to explicitly subclass UIBarButtonItems and then change every reference in my app to use the subclass (which will be tricky, as I am using some third-party libraries which just use UIBarButtonItem and I don't want to go messing with their implementation).
Any help would be greatly appreciated.
From what I remember from facing a similar issue, UINavigationBar will just take the tintColor and make it darker for the UIBarButtonItem (unless the style is set to BarStyleBlack, in which case it makes it a dull gray).
To do what you ask, I would create a custom UIButton with background images for the different control states that match your color scheme, then use this UIButton as the view for a custom UIBarButtonItem.
UIButton *customButton = [UIButton buttonWithType:...];
//normal_button.png and selected_button.png need to be created by you
[customButton setBackgroundImage: [UIImage imageNamed:#"normal_button.png"] forState:UIControlStateNormal];
[customButton setBackgroundImage: [UIImage imageNamed:#"selected_button.png"] forState:UIControlStateSelected];
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView: customButton];
If you want to try and encapsulate this, you could always create a factory or a custom init method on UIBarButtonItem (via a category) and use the above code (with slight modifications).
I am aware that I am not fully addressing your second point on just overriding the control state with a category. I don't know what method to override in UIBarButtonItem to do such a thing, but you may be able to accomplish what you want via method swizzling (http://cocoadev.com/index.pl?MethodSwizzling) once you find out which method you want to exchange.
I should note that I've only ever used swizzling for testing/debugging.
If you're using Interface Builder, drag and drop an UIButton to the navigation's bar right side, and it gets in as a right navigation bar button item. Then, configure different tints for different states of the button, and you're done.
Works in Xcode 10 and Swift 4.