Customizing UIBarButtonItems in various parts of applications (background image and shape) - ios

I want to change the background image of my UIBarButtonItems. In the root view, I want them to be a certain background image (but still rounded-rect buttons) in the nav bar, but in the next view, I have a UIToolBar where I want it to have different backgrounds yet again.
I used [[UIBarButtonItem] appearance] in my app delegate to change all of them, but I now realize for some I want it one style and for others yet another.
More importantly, I want to change not only the background image, but the shape for some. For one of the UIToolBar's UIBarButtonItems I want it to be in the shape of a back button in the navigation bar. How would I achieve this look?
Can I achieve both of these with the method outlined here?
Basically: How do I make custom UIBarButtonItems all over the app, and have some with different shapes?

If you want the buttons to look different in different view controllers, you should set them within the view controller, not in the delegate. Add code in either the init method or the viewWillAppear: method to customise the buttons. If you are customising UIToolbar items then use code similar to the link you gave. If it's for the navigation bar, do something like this:
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
//Customise button with background etc that you want
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:btn];
self.navigationItem.leftBarButtonItem = item;
//Release item if you're not using ARC

You can use the 'appearanceWhenContainedIn' method from the UIAppearance Protocol http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAppearance_Protocol/Reference/Reference.html
So for the Toolbar, you'd use:
[UIBarButtonItem appearanceWhenContainedIn:[UIToolbar class], nil]
And for the NavBar:
[UIBarButtonItem appearanceWhenContainedIn:[UINavigationController class], nil]

Related

Set the background color of my buttons excluding accessory buttons

I'm trying to globally change the color of my buttons, but I'm struggling with one in particular. I have a UITableView which in its cells I put an UITableViewCellAccessory. This is contained in a UIViewController and below this I have a UIStackView with a button inside, this is the one I want to change the background color.
I've trying
[[UIButton appearanceWhenContainedIn:[MyClass class], nil] setBackground:myColor];
But the problem is that it also paints the accessory
Also something like
[UIButton appearanceWhenContainedInInstancesOfClasses:#[[MyClass class], [UIViewController class], [UIStackView class]]] setBackground:myColor];
this one does nothing
Is there anything else I can try to achieve this?

UIButton appearance setBackgroundColor effecting navigation bar now after update

Xcode or iOS update has made the following code below function differently because now the navigation bar button background has a background color, unlike previously. Any fix? I want all buttons to have the same global color, but now it effects the navigation bar buttons which I dont want. I would like it transparent like before.
[[UIButton appearance] setBackgroundColor:[Helper getColor:self.application.color]];
As this particular UIButton is inside a UINavigationBar you could try applying a second specific appearance to 'override' the first general appearance set.
For example calling specifically,
[[UIButton appearanceWhenContainedIn:[UINavigationBar class], nil]
setBackgroundColor:[UIColor clearColor] forState:state barMetrics:metrics];
after you call,
[[UIButton appearance] setBackgroundColor:[Helper getColor:self.application.color]];
To override the general with the specific.
Docs Link: https://developer.apple.com/documentation/uikit/uiappearance

UINavigationBar back button icon

I would like to make a back and forward navigation from the start. So I added a Button inside the navigation bar however I would like the exact iOS icon with the back text after it.
How can I get this thing myself without the need to navigate programmatically? I use the storyboard.
Ignore the background color I mean this icon :
I do not use a navigation controller I use a page view controller and that is why. I don't know how this icon work if the text is part of the icon or not so I hope anyone knows.
I get now what you are trying to do. I did this not too long ago. I actually had to make the button myself. You said you have a leftbutton, this will need an outlet in your .h file. If you want we will call it leftButton for now. You will need some images so I am going to include the ones that I made. I made them in Paint Code. It is $99 USD but one of the best investments I ever made as an App designer. Here they are. I called them back and whiteSpace..
The last two images are white spaces so make sure you get them too. Drage them from this page to your desktop, then drag them to your project, make sure to click destination, copy into folder when you do this. Once you have the icons, the rest is done programmatically. In your viewDidLoad method you will change the appearance of your leftButton.
//First get the images
UIImage *arrow = [UIImage imageNamed:#"back.png"];
UIImage *wordSpace = [UIImage imageNamed:#"whiteSpace.png"];
//Next make a size of the image or it will be distorted
CGSize size = CGSizeMake(arrow.size.width + wordSpace.size.width, arrow.size.height);
//Put the two images together
UIGraphicsBeginImageContext(size);
[arrow drawInRect:CGRectMake(0, 0, arrow.size.width, size.height)];
[wordSpace drawInRect:CGRectMake(arrow.size.width, 0, wordSpace.size.width, wordSpace.size.height)];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//Assign the icon to the button
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:self action:#selector(backButtonClicked)];
[backButton setBackgroundImage:finalImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
//Move title over a bit to make it look nice
[backButton setTitlePositionAdjustment:UIOffsetMake(-20, 0) forBarMetrics:UIBarMetricsDefault];
//Make your button this new backButton
_leftButton = backButton;
Now that you have a custom back button you can assign the #selector(backButtonClicked). I am not sure about the fact that you are using a page controller, but in mine, I used a popViewController. But I did have a Navigation Controller in the project. You might need to call the proper VC with another method. But this is backButtonClicked.
- (void)backButtonClicked
{
//NSLog(#"going back");
[self.navigationController popViewControllerAnimated:YES];
//change to call your VC
}
So other than calling your desired view controller that should do it. If you don't know how to call a view controller programmatically, here is a link.

iOS custom shape navigation bar

I want to developer app with a custom navigation bar like in the following images:
I think that i need to subclass UINavigationBar and add button to centre of nav bar, but i don't really know how to make navigation bar look like on image. Can you please give me advice what should i do, links to any kind of documentation would be awesome!
Similar questions about navBar that doesn't helped me:
ios back button in the bar
Use custom Navigation Bar in iOS
Custom Navigation Bar in iOS 5
rogcar
EDIT:
My idea is next: make custom navigation bar height little bigger than default size, and add background image with arrow in it and with some transparency on the edges.
If you want a button (you probably do want) you can achieve it completely by subclassing UINavigationBar. You should remember that height of UINavigationBar is read-only property.
Style but not tappable:
So let's assume we subclass the navigation bar and add button there. You could do this and it will be going look great. For example:
- (void)drawRect:(CGRect)rect
{
self.backgroundColor = [UIColor lightGrayColor];
UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(self.frame.size.width/2-50, 0 , 100, 100)];
[myButton setBackgroundColor:[UIColor lightGrayColor]];
[myButton setTitle:#"Normal" forState:UIControlStateNormal];
[myButton setTitle:#"Highlighted" forState:UIControlStateHighlighted];
[self addSubview:myButton];
[self sendSubviewToBack:myButton];
}
But you will facing a problem that your button is non tapeable below UINvaigationBar. (I post an image on the bottom of the answer)
So there is clearly not a path you want to follow. Don't even try that.
Style but not tappable 2:
You may override this method in your navigation bar subclass
- (CGSize) sizeThatFits:(CGSize)size {
return CGSizeMake(custom_width, custom_height);
}
And then mask it using UIBezierPath for example
The right (tappable) way:
You have to create a view stick to your UINavigationBar. What i will do here (if you want it to every screen) is:
Make a Category of UIViewController which can draw (for example - this is easiest way) UIButton.
Style this 'UIButton' whatever you want (if you want
Pin action to 'UIButton': [btn addTarget:self action:#selector(menuShow:) forControlEvents:UIControlEventTouchUpInside];
menuShow: method should be declare in your category
You can call drawing button every time you want to redraw view controller.
As you can see there there will be two separates View: UINavigationBar and UIButton. This is allow you to set content under this little button and make it tapable.
So why just don't hide navigation bar, and use different view? Because iOS7 ;) When Apple change it in iOS7 for example then you have to rebuild your pseudo NavigationBar, with only additional view, you don't need to do anything.
You do not need to subclass UINavigationBar. Create UIView add to it UIImageView as background with image in the shape you need, add button.
Subclass UINavigationController hide UINavigationBar, add custom navigation bar.
First Hide navigation bar using -
self.navigationController.navigationBarHidden = YES;
Then create UIView with required height,height of navigationBar is 44px.Then create background image view, object of required UIButton and add all objects on created UIView as a subview.It will look like navigationBar.Thank you.
You can add your custom shaped view as titleView on the navigation bar.
Just make sure that clipsToBounds is set to NO, so it doesn't get clipped.

navcontroller - Setting up Navigation Item as image

I would like to setup the navigation controller bar button item to be an image.
I have read the following - Add image to a navigationItem's title
I understand how to setup this as an image. I am actually looking to set this up as the setting cog, within the bar button item (like a cog icon). I have seen this before in other apps, I would like to know if there is a default style to initialise for this or normally if this is achieved by the image route as above.
If this is above, does anyone know where this (kind of) default image styled icon is available, or would I need to make one?
Have you tried using the initWithCustomView option of UIBarButtonItem? A sample code will look like the below line.
UIBarButtonItem *aButton = [[UIBarButtonItem alloc] initWithCustomView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"settings.png"]]];
Another way to do this is,
UIBarButtonItem *aButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"settings.png"] style:UIBarButtonItemStyleBordered target:self action:#selector(buttonTapped)];
If you use storyboard, you can directly:
Drag a Button in the navigation bar instead of a Bar Button Item. It will automatically create a Button Bar Item for you with a Button inside it.
Enter a title for the Button Bar Item
Set an image for the Button with a Custom type.
It should works.

Resources