how to use UIAppearance appearanceWhenContainedIn: - ios5

I notice that in iOS5 we can custom UIKit control by UIAppearance and I start to use it.
I'd like to use appearanceWhenContainedIn: to custom the UINavigationBar's tintColor in different class, for example:
[[UINavigationBar appearanceWhenContainedIn:[A class], nil] setTintColor:[UIColor greenColor]];
[[UINavigationBar appearanceWhenContainedIn:[B class], nil] setTintColor:[UIColor redColor]];
However, it totally doesn't work. And I tried to add property in Class A/B like:
#property (strong, nonatomic) UIColor *tintColor UI_APPEARANCE_SELECTOR;
It seems workless too.
Any tips?
Thanks.

I attended the ios5 talk and asked this question.
Just like yakovlev refers, it's a good idea to subclass the UINavigationController.

Related

How do I set the default title view for my navigation controllers?

I'm writing an iOS 6 app and I want to set a title view that will show for all of my views, unless I specify otherwise. I've tried [[UINavigationBar appearance] setTitleView:view] and [[UIBarButtonItem appearance] setTitleView:view], but neither have worked.
Note: this title view cannot be a label, it must be a button.
Any ideas?
Are you using a UINavigationController?
If so, use something like the following to set the background image and font:
[[UINavigationBar appearance] setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor blackColor], UITextAttributeTextColor,
[UIFont fontWithName:#"HelveticaNeue-CondensedBold" size:22.0], UITextAttributeFont,nil]];
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navBar.png"] forBarMetrics:UIBarMetricsDefault];
If you only want to apply the changes to Navigation Bars in certain specific subclasses of UIViewController, then use something like the following:
[[UINavigationBar appearanceWhenContainedIn:[VCSubclassToChangeAppearance class], nil]
setBackgroundImage:[UIImage imageNamed:#"navBar.png"]
forBarMetrics:UIBarMetricsDefault];
You can also use this method for creating exceptions to the rule e.g. set one appearance for all, except one in particular.
If you want to change the appearance of the standard buttons on the nav bar, do something like this:
UIImage *standardBackgroundImage = [[UIImage imageNamed:#"navBarButton.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 8, 0, 8)];
[[UIBarButtonItem appearance] setBackgroundImage:standardBackgroundImage
forState:UIControlStateNormal
style:UIBarButtonItemStyleBordered
barMetrics:UIBarMetricsDefault];
In this example, every nav bar button (that's not a back button) and is of the UIBarButtonItemStyleBordered variety, will use the image. You'll need to work on the UIEdgeInsets for your particular button image.
You could try adding a subview (UITextField) to your navigation bar:
UITextField *titleField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100.0, 60.0)];
titleField.text = #"a title";
titleField.center = self.navigationController.navigationBar.center;
[self.navigationController.navigationBar addSubview:titleField];
You can define a global variable after that set title for each viewController by command:
self.title = kDefaultTitle
If you use story board, you can set it on each viewController in Title properties at right bar
Final: I think you can automatically set all title of view (exclude you attack to core)
Because UIBarButtonItem of different view controllers will change the title view of the navigation bar, you can not set the title view globally. You can use #Jake approach or subclass UIViewController in which you can override the setTitle method. And use that class as the superclass of all your own view controllers.
You can put any view into titleView in any ViewController which is wrapped in UINavigationController by following code.
self.navigationItem.titleView = yourView;
Try this one.

Tab bar controller controller color change

In my application i want to change the tab bar controller color,How to assign a custom color to the tab bar controller lik uinavigation bar in ios6?Can any one give me some refrences?
Put this on app delegate:
UITabBarController *tabBarController = (UITabBarController *) self.window.rootViewController;
tabBarController.view.tintColor = [UIColor redColor];
It's better than the first answer because it also changes the edit view tint color.
You can use the setTintColor option as described
[tabbarController.tabBar setTintColor:[UIColor greenColor]];
or you can set the background image
[tabbarController.tabBar setBackgroundImage:[UIImage imageNamed:#"tab_bg.png"];
if your TabBarController is defined int the AppDelegate you may need additional coding to access it.
First to set the background image
[[[[(UITabBarController *)[[(AppDelegate *)[UIApplication sharedApplication].delegate window] rootViewController]tabBar]setBackgroundImage:[UIImage imageNamed:#"tab_bg.png"]]]];
Second to set the tintcolor if required
[[[[(UITabBarController *)[[(AppDelegate *)[UIApplication sharedApplication].delegate window] rootViewController]tabBar]setTintColor:[UIColor redColor]]]];
dont forget to import your AppDelegate.h file.
You can use this call
tabbarController.tabBar.tintColor = [UIColor redColor];
To change only tabBar color, you can achieve by this:
tabbarController.tabBar.tintColor = [UIColor redColor];
But, for more, you need to create Custom TabBar and can do with it like color change, custom tabbar icon changes, etc.
Hope, it will be helpful to you.
Cheers.
Approach that worked for me (tested in iOS6) is:
[[UITabBar appearance]setTintColor:[UIColor redColor]];
in AppDelegate.h file in method application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions. Try this if it's still actual. I see the question still stays unsolved.

Remove custom image from navigation background for iOS 6

I have a MFMailComposeViewController that I'm presenting and I want to clear the image from the navigationBar.
On iOS 5, this works fine:
[self.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
But on iOS 6, this has no effect. How could I do this?
Thank you!
You jus hide the navigation bar..
self.navigationController.navigationBarHidden = YES;
or
[self.navigationController setNavigationBarHidden:YES animated:animated];
I'm sorry, I have to answer my own question. I made an error: I had set the UINavigationBar app-wide by doing
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"bar01.png"] forBarMetrics:UIBarMetricsDefault];
which had the effect of causing all navbars to have the bar01. Removing this line made it so that the MFMailComposer navbar was the default color with no need to nil out the image.

UITableViewController tintColor

I am trying to setTintColor for a viewcontroller that inherits from a UITableViewController.
I tried to put
[self.navigationController.navigationBar setTintColor:[UIColor blackColor]];
as the last line in loadView, but the color doesn't change. Where should I make this change?
Here is the interface definition of the controller:
#interface MyViewController : UITableViewController
{
Model *model;
NSArray * calculators;
}
#end
UPDATE: I finally put it in viewDidAppear and it worked.
Are you sure that your self.navigationController is not nil? This is a usual bug happenning all the time that you didn't present your MyViewController with a navigationController
Try this
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
I put my solution in the question.
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController.navigationBar setTintColor:[UIColor blackColor]];
}

Change iPhone navigation bar's height

My client can't read iPhone's default fonts, the size is too small. I have an application with a navigation bar and I need to make everything in it bigger, for example, the font's size.
IB doesn't seem to allow this... any help?
Many thanks!
Update: today (2012) there is a much bigger tendency towards custom UIs, so I would say the answer below is way too harsh. There is still no supported way of customizing height, though, but you can certainly derive from UINavigationBar and override some sizing methods. This probably will not get you rejected (although it is still a grey area, just something Apple will probably overlook today).
Once you get the size you want, you can use iOS 5 customization APIs to add the custom background image (see WWDC 2011 Session 114 - Customizing the Appearance of UIKit Controls).
Original answer from 2009:
This is generally impossible.
What's more, I believe making the navigation bar taller is a violation
of Apple Human Interface Guidelines, and your application may be
rejected from the App Store because of it. Please make sure your
client understands this risk before proceeding.
(Pointing out rejection risks is usually a good way to convince
clients against making nonsense decisions.)
Many of the answers here are incorrect, or incomplete, so I wanted to add my answer here in the hope that it might enlighten some.
First off, there is nothing wrong with changing the height of the navigation bar. People commenting saying its not allowed, or goes against the guidelines are simply misunderstanding those guidelines.
The ability to adjust or alter the default navigation bar that's used inside a UINavigationController has been part of the SDK since iOS 5.
- (instancetype)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass NS_AVAILABLE_IOS(5_0);
The easiest way to change the height of the status bar is to use this method when initialising your navigation controller, passing in your custom UINavigationBar sub-class.
TestViewController *t = [[TestViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithNavigationBarClass:[MyNavigationBar class] toolbarClass:[UIToolbar class]];
[nav setViewControllers:#[t]];
[self.window setRootViewController:nav];
[self.window makeKeyAndVisible];
Where an example of such a custom UINavigationBar class could look like:
#interface MyNavigationBar : UINavigationBar
#end
#implementation MyNavigationBar
- (CGSize)sizeThatFits:(CGSize)size
{
CGSize s = [super sizeThatFits:size];
s.height = 90; // Or some other height
return s;
}
#end
If you decided to just change the font size in the navigation bar, you can do this (usually in your UIViewController's viewDidLoad method):
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[titleLabel setBackgroundColor:[UIColor clearColor]];
// here's where you can customize the font size
[titleLabel setFont:[UIFont boldSystemFontOfSize:18.0]];
[titleLabel setTextColor:[UIColor whiteColor]];
[titleLabel setText:self.title];
[titleLabel sizeToFit];
[titleLabel setCenter:[self.navigationItem.titleView center]];
[self.navigationItem setTitleView:titleLabel];
[titleLabel release];
By subclassing you can achieve that and still support iOS 3+:
Complete example:
#import <UIKit/UIKit.h>
#interface ASNavigationBar : UINavigationBar
#property (nonatomic , retain) UIImage *backgroundImage;
#end
And implementation:
#import "ASNavigationBar.h"
#implementation ASNavigationBar
#synthesize backgroundImage = _backgroundImage;
-(void) setBackgroundImage:(UIImage *)backgroundImage
{
if (_backgroundImage != backgroundImage)
{
[_backgroundImage release];
_backgroundImage = [backgroundImage retain];
[self setNeedsDisplay];
}
}
-(void) drawRect:(CGRect)rect
{
// This is how the custom BG image is actually drawn
[self.backgroundImage drawInRect:rect];
}
- (CGSize)sizeThatFits:(CGSize)size
{
// This is how you set the custom size of your UINavigationBar
CGRect frame = [UIScreen mainScreen].applicationFrame;
CGSize newSize = CGSizeMake(frame.size.width , self.backgroundImage.size.height);
return newSize;
}
#end
Important notes:
If the background image is with transparent areas, you have to set its barStyle property to "translucent" or the transparent areas will be black.
If you have a NavigationBar taller than 44 points, you have to take into account that the position of the BarButtonItems might not be correct. They all will be anchored to the bottom of the bar. you can fix that by overriding layoutSubviews and change their origin.y value.
You should not change the height of the navigation bar. From Apple Programing Guide on View Controller:
Customizing the Navigation Bar Appearance
In a navigation interface, a navigation controller owns its UINavigationBar object and is responsible for managing it. It is not permissible to change the navigation bar object or modify its bounds, frame, or alpha values directly. However, there are a few properties that it is permissible to modify, including the following:
● barStyle property
● translucent property
● tintColor property
(taken from Apple: https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/NavigationControllers.html)
UPDATE -- IOS 7 --- still only the available properties can be changed but below is a great tutorial on how to achieve flexibility in the navigation bar http://www.appcoda.com/customize-navigation-status-bar-ios-7/
To add to Skela's answer:
If you initiate your navigation controller in the Storyboard you can change the class of your UINavigationBar in the storyboard to your custom navbar.
and then implement the change height in the class
#interface MyNavigationBar : UINavigationBar
#end
#implementation SwitchAssessmentNavigationBar
- (CGSize)sizeThatFits:(CGSize)size
{
CGSize s = [super sizeThatFits:size];
s.height = 200; // Or some other height
return s;
}
#end