How to add an image on UINavigationBar - iphone

How do i add a small image on a UINavigationBar ? It should display in front of the title. Its small and 40X40 pixel in size.
noteL: I don't want to add an image to the background to add this tiny image. Furthermore this should work for both iOS4 and 5

On a Navigation bar you can set both right and left buttons like this:
UIImage * myIcon = [UIImage imageNamed:#"icon.png"];
[self.navigationItem setLeftBarButtonItem:[[UIBarButtonItem alloc] initWithImage:myIcon
style:UIBarButtonItemStyleBordered target:self action:#selector(someAction:)]];
To the right button just message setRightBarButtonItem

Related

iPhone: How to make UIButton which you can easily tap?

I'm making customized navigation bar by using UIView and UIButtons instead of UINavigationBar.
But my UIButtons on the navigation bar doesn't response sensitively.
I have to tap almost center of the UIButton to tap.
It doesn't respond if I tap edge of the UIButton.
But buttons on normal UINavigationBar can be tapped by tapping edge of the button.
Even by tapping outside of the button, it can be tapped.
Shutter button or Option button on the camera app also can be tapped by tapping edge or outside of buttons.
How can I implement those easily tappable buttons to my app?
Use an image and create a custom button. Set the button so the image does not scale to the size of the button's view, but instead will just Center. Expand the button's size so it is larger than the image on each side. Apple does this as well with things like tab buttons.
UIButton has an imageEdgeInsets property specially for this purpose. Just make a UIButton frame as big as you need for touchable area and than scale image inside it appropriately, using imageEdgeInsets.
Disclaimer: This code has not been tested, but it gives you an idea of how it could be done.
You make a button (in this case 40px x 40px), and then add a background image to it which is smaller, hence gives the impression of that the image is very "clickable".
// This image is 20px x 20px (Just an example)
UIImage* backgroundImage = UIImage imageNamed:#"backgroundImage.png"]
// Custom button, remember to add a target method
UIButton* customButton = [UIButton buttonWithType:UIButtonTypeCustom];
customButton.frame = CGRectMake(0.0, 0.0, 40.0, 40.0);
customButton.contentMode = UIViewContentModeCenter;
[customButton setImage:backgroundImage forState:UIControlStateNormal];
UIBarButtonItem* customBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customButton];
self.navigationItem.rightBarButtonItem = customBarButtonItem;
[customBarButtonItem release];

Placing a custom view based UIBarButtonItem in the navigation bar without default horizontal padding

How do I remove the horizontal padding to the left and right of custom left and right UINavigationBar items? There seems to be ~ 10 points of padding that iOS sets by default.
I'm customizing left and right navigation bar buttons (I have given up on trying to set my own backButtonItem, so I'm just using the leftBarButtonItem).
In either case (left or right), pressing these custom buttons indicates that Apple seems to preserve some padding to the left of the leftBarButtonItem, and to the right of the rightBarButtonItem; regardless of how wide I make the custom background and image properties of the UIButton I place inside the left/right bar button item as its custom view.
Since UIBarButtonItems have no "frame" I can access, I can't position them within their superview like I can normal UIViews.
Any suggestions on how to remove this default padding? See screen shot attached to see the bit I'm trying to reduce to a zero width. In the screen shot, the plus icon appears shifted to the right because I gave it an inset; but the highlighted background image, also presumably using that inset, is getting clipped on its right side).
See image at: https://skitch.com/starbaseweb/rj2e5/ios-simulator
For reference, here's how I'm creating my custom UIBarButtonItem (in this case, it's the right button):
- (UIBarButtonItem *)customAddButtonItemWithTarget:(id)target action:(SEL)action {
UIButton *customButtonView = [UIButton buttonWithType:UIButtonTypeCustom];
customButtonView.frame = CGRectMake(0.0f, 0.0f, 45.0f, 44.0f);
[customButtonView setBackgroundImage:
[UIImage imageNamed:#"bgNavBarButton-OutsideRight-Normal.png"]
forState:UIControlStateNormal];
[customButtonView setBackgroundImage:
[UIImage imageNamed:#"bgNavBarButton-OutsideRight-Highlighted.png"]
forState:UIControlStateHighlighted];
[customButtonView setImage:
[UIImage imageNamed:#"bgNavBarButton-Add-Normal.png"]
forState:UIControlStateNormal];
[customButtonView setImage:
[UIImage imageNamed:#"bgNavBarButton-Add-Highlighted.png"]
forState:UIControlStateHighlighted];
[customButtonView addTarget:target action:action
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *customButtonItem = [[[UIBarButtonItem alloc]
initWithCustomView:customButtonView] autorelease];
[customButtonView setImageEdgeInsets:UIEdgeInsetsMake(0.0f, 10.0f, 0.0f, 0.0f)];
//customButtonItem.imageInsets = UIEdgeInsetsMake(0.0f, 10.0f, 0.0f, 0.0f);
return customButtonItem;
}
55As commented above, the solution I went with is based on this answer to a different, but very much related question: How to adjust UIToolBar left and right padding. It is also facilitated by (and depends on) iOS5, which allows you to set multiple buttons on the left or right side, instead of just one.
Here's an example of removing the padding to the left of a custom left button item:
UIBarButtonItem *backButtonItem // Assume this exists, filled with our custom view
// Create a negative spacer to go to the left of our custom back button,
// and pull it right to the edge:
UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
target:nil action:nil];
negativeSpacer.width = -5;
// Note: We use 5 above b/c that's how many pixels of padding iOS seems to add
// Add the two buttons together on the left:
self.navigationItem.leftBarButtonItems = [NSArray
arrayWithObjects:negativeSpacer, backButtonItem, nil];
And with this, the left padding for the left bar button item in a navigation bar, is gone!
NOTE: This has worked for me in iOS5 and iOS6. Given that iOS7 is considerably different (from the public demos), those of you with the early seeds of iOS7 should test if something so unintentional, like this hack, will actually continue to work for you beyond iOS6.
I have tried this and it works:
1) Create a custom UIToolbar subclass, which does nothing in -drawRect:, and is not opaque, and has backgroundColor = [UIColor clearColor].
2) Create a custom UIBarButtonItem with the toolbar as the custom view.
3) Add your buttons to the custom toolbar.
4) In your custom toolbar override -layoutSubviews and do your own spacing.

Is it possible to change a bar button background image while we click on it?

I have a barbuttonitem which i have customised using a custom button with an image. I want to change this image everytime after I click it. Like on and off. Once I click it it will show OFF image. Then again it will go ON image.
Is it possible?
Yes. In your target method just change out the UIBarButtonItem
- (void)toolbarButtonPressedAwesomeMethod {
Do awesome stuff...
// Change the button here…
UIBarButtonItem *bbi = [[[UIBarButtonItem alloc] init…
// Set it in the view
[self.navigationItem setRightBarButtonItem:bbi];
}
yourButton.image = [UIImage imageNamed:#"yourImage"];
UIBarItem Documentation

UIBarButtonItem black instead of white

I have that Navigation Controller and I'm adding 1 button by code this way:
UIBarButtonItem *configButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"config.png"] style:UIBarButtonItemStyleBordered target:self action:#selector(showConfigWindow)];
self.navigationItem.leftBarButtonItem = configButton;
It's working right but the icons are black instead of white!!
If I use this:
UIBarButtonItem *configButton = [[UIBarButtonItem alloc] initWithTitle:#"Settings" style:UIBarButtonItemStyleBordered target:self action:#selector(showConfigWindow)];
The text is showed properly in white.
The icons are ok cause I'm using them through interface builder and they show right.
UIBarButtonItem renders images in grayscale according to the images alpha value. So, if your image is fully opaque, then it will always render black, no matter what color the source image is, but if your image is transparent, it will render some shade of grey.
In order to render it fully white, or a color, you need to create a custom UIBarButtonItem. See Can I have a UIBarButtonItem with a colored image? for details

Can I have a UIBarButtonItem with a colored image?

I have an image that I want to display on a UIBarButtonItem, but for some reason it only shows the outline of it and the rest is all white. How can I have it actually display the image?
Thanks!
There's other iOS7+ solution:
NSString *iconFilename = // ...
UIImage *image =
[[UIImage imageNamed:iconFilename]
imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIBarButtonItem *barButtonItem =
[[UIBarButtonItem alloc] initWithImage:image
style:UIBarButtonItemStylePlain
target:self
action:#selector(onBarButtonItemTapped:)];
Swift 5:
let iconFilename: String = // ...
let image = UIImage(named: iconFilename)?.withRenderingMode(.alwaysOriginal)
let barButtonItem = UIBarButtonItem(image: image,
style: .plain,
target: self,
action: #selector(onBarButtonItemTapped(_:)))
Extract from UIImage.h:
... navigation bars, tab bars, toolbars, and segmented controls automatically treat their foreground images as templates ... You can use UIImageRenderingModeAlwaysTemplate to force your image to always be rendered as a template or UIImageRenderingModeAlwaysOriginal to force your image to always be rendered as an original.
UPDATE: See MANIAK_dobrii's answer for an easier solution, available in iOS 7+.
Here is how I use an image for a UIBarButtonItem:
UIImage *image = [UIImage imageNamed:#"buttonImage.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.bounds = CGRectMake( 0, 0, image.size.width, image.size.height );
[button setImage:image forState:UIControlStateNormal];
[button addTarget:myTarget action:#selector(myAction) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
…
There is another way that does not involve coding at all.
First, place the images you want to put on the bar on the Assets.xcassets document.
Select the image on the assets browser.
Open the Attributes inspector for that image on the right vertical toolbar.
On "Render As" select "Original Image".
Even though on the storyboard the buttons will continue to be painted with the tint color, when running on the simulator the original image will be shown.
The default rendering mode for an image varies from one UI control to the other. If you set this parameter on the attributes inspector, though, you can force that an image will be always represented with a specific rendering mode.
If you need the same image to be represented with different rendering modes on different controllers, then the response from MANIAK_dobrii is more appropriate.
In Swift 3:
let iconname = // ...
let image = UIImage(named: iconname)?.withRenderingMode(.alwaysOriginal)
let barButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(self. onBarButtonItemTapped))
self.navigationItem.leftBarButtonItem = barButtonItem
Nope. As you can read in the Human Interface Guidelines
After you’ve decided on the appearance of your icon, follow these guidelines as you create it:
Use the PNG format.
Use pure white with appropriate alpha.
Do not include a drop shadow.
Use anti-aliasing.
If you decide to add a bevel, be sure that it is 90° (to help you do this, imagine a light source positioned at the top of the icon).
For toolbar and navigation bar icons, create an icon that measures about 20 x 20 pixels.
For tab bar icons, create an icon that measures about 30 x 30 pixels.
Note: The icon you provide for toolbars, navigation bars, and tab bars is used as a mask to create the icon you see in your application.
It is not necessary to create a full-color icon.