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]]];
Related
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.
I'd like to put a search bar in my navigation bar, like safari has. If I add a UISearchBar to my view, it ends up underneath the navigation bar instead. How can I put a search bar in (not under) a unnavigationbar?
Try putting UISearchBar or UITextField in titleView of UINavigationItem and then set this in topItem of navigation bar.
Refer to human interface guideline to confirm that it is allowed.
I do it this way:
UISearchBar * navSearchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 232, 44)];
navSearchBar.delegate = self;
self.navigationItem.titleView = navSearchBar;
[navSearchBar release];
I hope it helps!
A navigationBar is mostly used to navigate a view hierarchy. If all you need is a search bar on the top of the page, why wont you just use a regular searchBar with a background similar to the navigationBar?
That way you will have much more control on the layout of the search bar, and you won't have to deal with the navigationBar.
By the way, this is probably the way the safari app actually work - it doesn't place the searchBar inside a navigationBar. You can see this by the fact that the searchBar is scrolled and doesn't stay on top.
I have an application with a tab bar and a navigation bar. I push a view controller that is used to show photos, one at a time. It initially shows the bars and forward/back controls; after a delay, these hide, using setNavigationBarHidden:animated: and a custom transform (CGAffineTransformMakeTranslation) on the tab bar. This works, but the view controllers view , which shows the photo, leaps up and down. The same is true if I leave the tab bar out of the equation.
How can I prevent the UINavigationBar from moving my view around? I would like the photo to stay fixed in the screen, with the nav bar dropping down over the top segment of it.
Had this issue and fixed it with a class that inherited from UINavigationController
-(void)viewWillAppear:(BOOL)animated
{
self.navigationBar.translucent = YES;
}
Worked great for me, didn't had to set style to UIBarStyleBlackTranslucent. So it did kept my colors.
[[navigationController navigationBar] setBarStyle:UIBarStyleBlackTranslucent];
[[navigationController navigationBar] setAutoresizesSubviews:NO];
this seemed to do the trick for me!
I know this is an old question, but I accomplished that by disabling 'Autoresize Subviews' in Interface Builder
I haven't been able to find a proper way to handle this except to set the navigationBar style to translucent as in:
theNavigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
Other than creating another navigation bar and adding buttons to them, that's the best (and it seems to be what Apple does as well in it's Photo app)
I'm current creating a UISegmentedControl programmatically in a view controller's viewDidLoad method and adding it to the view controller's navigation bar by assigning it to self.navigationItem.titleView.
That's easy enough, but I'd like to be able to do this in Interface Builder as well and so far haven't been able to figure out how. Google hasn't been much help either. Can someone describe how to do this in IB or point to an online example? I'd be much appreciative.
Thanks,
Howard
If you've got whole nav stack in the nib, it's actually pretty easy; you can just drag it into the title area and IB does the right thing automatically.
Otherwise, you can just add the segmented control to the nib (not necessarily a subview) and then add an #property IBOutlet to it from your view controller. Then in viewDidLoad, assign it to the titleView as normal. Remember to release in dealloc, and you're golden.
In IB you certainly can just drag a view into the middle of the navigation controller and it will work fine if its just inside one navigation item.
However, if the same view object reference is dragged into the title view area of different navigation items that will at some point be pushed onto the navigation controllers stack, you will run into problems with the title view disappearing when you travel back through the stack. The navigation controller isn't too happy with references to the same object popping up on multiple navigation items for some reason and it only throws a fit when you pop back to the view with the troublesome navigation item.
To get around this you MUST explicitly set and unset the titleView object when the you navigate to the views using the shared title view object reference. For instance, if you had custom logic behind a subclassed view set as the titleView that you only wanted to instantiate once.
Alternatively, you could store the UISegmentedControl designed in IB in it's own NIB. Then set the FileOwner to the viewcontroller class that will be using the segmentedControl instance. In the viewcontroller class, declare the segmentedcontrol as an IBOutlet Property and link it to the instance in the nib.
All left to using the designed instance is then to call:
[[NSBundle mainBundle] loadNibNamed:#"TTCustomSegmentedControl"
owner:self
options:nil];
self.navigationItem.titleView = sortSegmentControl;
Just try this (works for me):
UISegmentedControl *mSegmentedControl = [[UISegmentedControl alloc] initWithItems:
[NSArray arrayWithObjects:
#"Segment 1",
#"Segment 2",
nil]];
mSegmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
mSegmentedControl.tintColor = [UIColor redColor];
[mSegmentedControl setSelectedSegmentIndex:0];
[mSegmentedControl addTarget:self action:#selector(sectionPress:)
forControlEvents:UIControlEventValueChanged];
self.navigationItem.titleView = mSegmentedControl;
You can't set the titleView property in IB, but you may be able to create / set up the control as a child of your controller's view via Interface Builder, and then in your viewDidLoad method, remove it from your view and set it as the titleView:
[segControl removeFromSuperview];
self.navigationItem.titleView = segControl;
I am using my own custom navigationBar, but i need to access it in a number of different views because i need to add buttons, change title and so forth.
Should i pass a reference to my navigationBar each time i show a new view, or just make it a singleton so i can access it from any view?
Neither.
You've listed adding buttons and changing titles as the reasons you need a custom toolbar, but both of those things can be done through the navigation controller with no need to create your own and therefore no need to create a singleton or a global variable.
When you push a new view controller, you can set the title for the navigation bar simply by calling [self setTitle:#"Nav Title"]; in the -viewDidLoad of that view controller. If you need to add a button, use code like the following (also in -viewDidLoad):
[[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemEdit
target:self
action:#selector(setEditing)] autorelease]];
In other words, your design is flawed if you are creating a custom navigation bar only for the reasons you've listed. I suppose there are some good reasons to create a custom navigation bar, but these are not among them.
Consider reviewing the Configuring the Navigation Item Object section of the View Controller Programming Guide for iPhone OS.
Best regards,
Are you using a UINavigationController? If so, you can access the navigation bar from any sub-controller like this:
UINavigationBar *bar = self.navigationController.navigationBar;
Make it a global variable.