appearanceWhenContainedIn not working as expected - iphone

I'm using iOS's UIAppearanceProxy to customize the look of my app.
In most of the app, I want the navBar to have one background image. In one specific section of the app, I want the navBar to have a different background image.
Here's what I'm doing in application:didFinishLaunchingWithOptions:
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navbar_bg1"]
forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearanceWhenContainedIn:[DiscoverViewController class], nil] setBackgroundImage:[UIImage imageNamed:#"navbar_bg2"] forBarMetrics:UIBarMetricsDefault];
I would like to keep all my appearance code in one place instead of overriding the navBar in a specific view controller.
Also helpful to know is that my app is structured with a TabBarController, where each tab controls a NavigationController which owns a subclassed ViewController, like DiscoverViewController above.
What am I doing wrong?

As you just stated, the navigation bar is not contained in the DiscoverViewController in your hierarchy; rather, both are contained in a navigation controller. One way to keep the appearance code centralized is to create an empty subclass of UINavigationController and instantiate that instead of UINavigationController in the relevant place (whether that's a nib or storyboard or just programmatically). Then, to style child elements, get their appearance proxy "when contained in" DiscoveryNavigationController or what have you. I've used this method with good results in the past.

Related

MPMediapickercontroller tab bar overlap with custom tab bar in iPhone

I can hide or unhide tab bar in navigation controller. But issue when I use presentModelViewController of MPMediapickercontroller, and even when hiding custom tab bar, it overlaps the tab bar of MPMediapickercontroller.
Please take a look at this image.
This is a default 'MPMediapickercontroller' presented.
I have been surfing to find this fix but with no success.
In MPMediapickercontroller its always present modally. so one solution for that is you have to use image which is same as tabbar of MPMediapickercontroller.
Here is that image. use without any border just white image thats it.
Now, below is my code.
In Viewwillappear method you have to set that image in tabbar appearance.
-(void)viewWillAppear:(BOOL)animated
{
[[UITabBar appearance] setBackgroundImage:[UIImage imageNamed:#"tabDefault"]];
[super viewWillAppear:YES];
}
Then whatever you want presentModelViewController of MPMediapickercontroller
in last you done all things then you have to use dealloc method to set Tabbar same as you required permanent.
-(void)dealloc
{
[[UITabBar appearance] setBackgroundImage:[UIImage imageNamed:#"tab2"]];
}
I solved my problem from this. hope you done it.

UITableView appearance with ios5 UIAppearance not working correctly?

I'm trying to set the background for a number of UITableViews that are loaded inside a UINavigationController. I'm using the appearance proxy added in iOS 5 but it's not working how I'm expecting it to.
The app uses a UISplitViewController, with the master view being the UINavigationController.
Inside this, I have a UITableViewController subclass called PBMasterTableViewController.
In my AppDelegate I have the following :
UIImageView *bgView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"menuBg.png"]] autorelease];
[[UITableView appearanceWhenContainedIn:[PBMasterTableViewController_Ipad class], nil] setBackgroundView:bgView];
This is working fine, and my main menu in the split view has the background that I want.
From this main menu, I 3 other UITableViewController sublasses that are pushed onto the nav controller when I select the relevant rows. I cannot however get the background of these tables to change using the appearance proxy. I'm trying the following :
UIImageView *bgView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"menuBg.png"]] autorelease];
[[UITableView appearanceWhenContainedIn:[PBTwitterTableViewController class], nil] setBackgroundView:bgView];
This is also in the appDelegate right below the code previously shown that works (without the repetition of the image view creation however) but this simply does nothing! When I push an instance of the PBTwitterTableViewController onto the nav controller, I simply get a standard table view with no background change.
I know that I could simply change the background views in the tableViewControllers themselves, however I don't want these backgrounds to be there when the menu is shown in the splitViewControllers popover when rotated to portait, hence I am trying to use appearanceWhenContainedIn:
I also don't want to simply set the appearance to be when contained in the UISplitViewController, as in 2 instances I have a UITableView being loaded into the detail section, so this would then change the appearance of those which I do not want.
Is there another way of doing this without the appearance proxy that will still allow me to change the background for when it is in the popover, or is there a way of making this work with the proxy, or am I just missing something stupid?
Thanks
EDIT :
I've just tried creating a subclass of the UINavigationController and tried using [[UITableView appearanceWhenContainedIn:[PBMenuNavigationController class], nil] setBackgroundView:bgView]; which is again working fine for the main menu, but not for any other UITableView pushed onto the stack, so I'm really stumped now :(
OK sorted it. Just doing it inside each view and checking that the parent controller isn't something that I don't want. Thanks anyway

adding UIButton to UIView or UINavigationBar doesn't work

I am trying to add a UIButton to a UINavigationBar with the following:
UIButton * addSource = [UIButton buttonWithType:UIButtonTypeCustom];
[addSource setBackgroundImage:[UIImage imageNamed:#"addsource.png"] forState:UIControlStateNormal];
[addSource addTarget: self action:#selector(addSourceButton:) forControlEvents:UIControlEventTouchUpInside];
[addSource setFrame: CGRectMake(115, 5, 32, 32)];
[navBar addSubview:addSource];
[addSource release];
However this doesn't work, any idea? When I comment out the setBackgroundImage and change it to setBackgroundColor I can see it, but I can't seem to click on it (i.e: the action in which it's set to is not triggered). Any idea? Changing it to a UIImageView instead of a UIButton also works, I can see the image just fine, so this clarifies that the image is there.
You can not add a UIButton to a UINavigationBar. Use a UIBarButtonItem.
From Apple docs:
Unlike other types of views,
you do not add subviews to a navigation bar directly. Instead, you use
a navigation item (an instance of the UINavigationItem class) to
specify what buttons or custom views you want displayed.
and:
A bar button item is a button specialized for placement on a UIToolbar
or UINavigationBar object. It inherits basic button behavior from its
abstract superclass, UIBarItem. The UIBarButtonItem defines additional
initialization methods and properties for use on toolbars and
navigation bars.
”
Adding Content to a Navigation Bar
When you use a navigation bar as a standalone object, you are responsible for providing its contents. Unlike other types of views, you do not add subviews to a navigation bar directly. Instead, you use a navigation item (an instance of the UINavigationItem class) to specify what buttons or custom views you want displayed. A navigation item has properties for specifying views on the left, right, and center of the navigation bar and for specifying a custom prompt string.
A navigation bar manages a stack of UINavigationItem objects. Although the stack is there mostly to support navigation controllers, you can use it as well to implement your own custom navigation interface. The topmost item in the stack represents the navigation item whose contents are currently displayed by the navigation bar. You push new navigation items onto the stack using the pushNavigationItem:animated: method and pop items off the stack using the popNavigationItemAnimated: method. Both of these changes can be animated for the benefit of the user.
In addition to pushing and popping items, you can also set the contents you could also use of the stack directly using either the items property or the setItems:animated: method. You might use these methods at launch time to restore your interface to its previous state or to push or pop more than one navigation item at a time.
If you are using a navigation bar as a standalone object, you should assign a custom delegate object to the delegate property and use that object to intercept messages coming from the navigation bar. Delegate objects must conform to the UINavigationBarDelegate protocol. The delegate notifications let you track when navigation items are pushed or popped from the stack. You would use these notifications to update the rest of your application’s user interface.
For more information about creating navigation items, see UINavigationItem Class Reference. For more information about implementing a delegate object, see UINavigationBarDelegate Protocol Reference."
from UiNavigationBar class reference.
please also refer UIBarButoonItem -(id)initWithCustomView:(UIView*)view. pleae note UIbutton is subclass of uiview
also refer uinavbaritem's
rightBarButtonItem property
– setLeftBarButtonItems:animated:
– setLeftBarButtonItem:animated:
– setRightBarButtonItems:animated:
– setRightBarButtonItem:animated:
and titleview.
you have to use a UIBarButton item, heres the code:
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(dismissView)];
self.navigationItem.leftBarButtonItem = cancelButton;
[cancelButton release];
If you want to add something in the centre in your navigation bar, why don't you just do
navbar.titleView = addSource

colors dont show up on UINavigationBar

I know this may be a pretty open ended question, but I am trying to set a different color to my navigation bar using this:
self.navigationController.navigationBar.tintColor = [UIColor greenColor];
And from some reason in one view controller I do get green color and in another one I am not getting the green color. I am calling this in viewdidLoad.
Is there something that could override that? (I am not overriding drawRect).
Happy to provide any code if necessary, but this really puzzels me.
Thanks!
Maybe you're using a second UINavigationController instance in one of your view controllers?
That could happen if you're presenting a UIViewController modally (UIViewController method presentModalViewController:animated:).
If you're presenting a UIViewController that's not on the same "navigation stack" (managed by the original UINavigationController), you would have to apply the same tintColor to its UINavigationBar.

MFMailComposeViewController is acctually a navigation controller?

When I try to push my MFMailComposeViewController it says I can't push navigation controllers?! Hmm... dunno about that.
Basically all my view controllers are actually subclasses of CustomUIViewController which automatically removes the title view from the navigation bar (as I have a logo in the navigation bar instead).
Presenting my MFMailComposeViewController modally puts the title back in there because I can't make it subclass CustomUIViewController (or can i? I dunno?).
So I really need a way to remove the title view from the MFMailComposeViewController.
Thanks
Tom
A few easy options:
Subclass MFMailComposeViewController too.
Don't subclass CustomUIViewController; override some methods in a category of UIViewController (icky).
Hide the title item in a category of UINavigationBar
Considering the title view contains the Cancel and Send buttons, I'm not sure you'd want to remove it. You could try changing the actual title in the navigation bar with
mailController.navigationItem.titleView = myLogo;
Which should set that center area of the nav item to be your logo instead of some text.
Although it would be nice to get more control over the appearance, I don't think there is a clean method. When you can't change it, I think you should hide it:
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects:[UIColor clearColor], nil] forKeys:[NSArray arrayWithObjects:UITextAttributeTextColor, nil]]];