Iphone Interface Builder - Toolbar Image always displays as white box - iphone

I am trying to use my own custom image to represent my toolbar buttons, however, whenever I set the image (a png image) as the toolbar button's image, it just displays as a white box the size of the image on my button.
Programmatically I tried this:
bestButton.image = [UIImage imageNamed:#"best_off.png"];
Where bestButton is a UIBarButtonItem declared and set as a property and IBOutlet.
However, this also just displays a white box where the button should be.
To check if the image is bonked, I tried this code:
self.navigationItem.titleView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"best_off.png"]]autorelease];
Which correctly sets my titleview in the navigation bar to show the image perfectly.
Can anyone help identify why this, and all my other images just show as white boxes when put in the bar button's image?

The images used in toolbars are never displayed. They are used as a mask (the alpha channel I believe). Try this. Create an icon (png) with transparent background. Where ever you have a pixel set, it will be white in your icon displayed in the toolbar.

I did this by iterating over all of the bar-items in the toolbar and for those items that were a button, not a space, I set the customView to that of a new button with my image and hooked up the same TouchUpInside listener that I used for the corresponding toolbar button. The buttons even glow. The images have to be 30x30.
If you dont mind looking at MonoTouch instead of Objective C, here is the code. It could be translated easily to Obj C.
void InitializeTbButtons (UIToolbar toolbar, string[] imageFilePaths, EventHandler[] buttonHandlers)
{
int i =0;
foreach (UIBarButtonItem item in toolbar.Items)
{
if ((item.Image != null) && (( i < imageFilePaths.Length) && (i < buttonHandlers.Length) ) )
{
UIButton btn = new UIButton( new System.Drawing.RectangleF(0,0,30,30) );
string filePath = imageFilePaths[i];
btn.SetImage( UIImage.FromFile(filePath), UIControlState.Normal );
btn.ShowsTouchWhenHighlighted = true;
EventHandler eventHandler = buttonHandlers[i];
btn.TouchUpInside += eventHandler;
item.CustomView = btn;
i++;
}
}
}

You can create customView of UIBarButtonItem and assign to navigationItem. Here is the example...
UIImage *bestImage = [UIImage imageNamed:#"best_off.png"];
UIImageView *bestView = [[UIImageView alloc] initWithImage:bestImage];
UIBarButtonItem *bestButton = [[UIBarButtonItem alloc] init];
bestButton.customView = bestView;
self.navigationItem.rightBarButtonItem = bestButton;

Related

Image View in Button Doesn't Appear

I am trying to use the background view of the image view of a UIButton but for some reason it will not show up. This is what I have tried:
detailCell.greenPriorityButton.imageView.frame = detailCell.greenPriorityButton.frame;
[detailCell.greenPriorityButton.imageView setBackgroundColor:[UIColor greenColor]];
[detailCell.greenPriorityButton.imageView setHidden:NO];
[detailCell.greenPriorityButton.imageView setOpaque:YES];
I have called NSLog on the imageView property and it seems everything is as it should be. I can also tap on the button and the method associated with it will be called so I know it exists. Just in case I am missing something here is the NSLog return:
<UIImageView: 0x1d97e1b0; frame = (254 61; 20 20); clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x1d97e210>>
The reason I am not using dot notation to set the image view properties above is because they don't seem to change the values. For example, if I say detailCell.greenPriorityButton.imageView.hidden = NO; it doesn't seem to do anything.
Thanks for any help!
Edit
The reason for not just setting the background color of the button and not its image view is because I am trying to create a small shape in the button. However I want the tappable space to have margins around the shape so it is still user friendly. I thought the image view property would lend useful as I could manipulate the frame and layer of that separately from the frame and layer of the button.
I have now tried adding a UIView *greenBackground as a subview to the button, however this doesn't appear either.
If you want a view that you can have within the view of the button for the purpose of setting its color then I would think that trying to use the imageview is the wrong approach. You could just add a subview that has the changed background color. something like this:
UIView *colorView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 10, 10)];//Whatever rect you want that will be in reference to the frame of the button
colorView.backgroundColor = [UIColor greenColor];
[detailCell.greenPriorityButton addSubview:colorView];

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];

How to add an image on UINavigationBar

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

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

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.