I'm implementing the TTThumbsViewController from the Three20 project and things are finally starting to take shape. I push the TTThumbsViewController from the current view controller by just pushing it onto the current stack and animate the transition (common navigation controller push).
My problem is that when I pop the TThumbsViewController view controller, the navigation controller is stuck in a mode where its view controllers are drawn UNDER the navigation bar (which is now translucent).
Start
Push
Pop
You need to reconfigure the original style of the status bar, navigation bar & tool bar when your view reappears. You can do this by implementing viewWillAppear: in your view controller:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
UINavigationController* navController = self.navigationController;
navController.navigationBar.barStyle = UIBarStyleDefault;
navController.navigationBar.tintColor = [UIColor redColor];
navController.toolbar.tintColor = [UIColor redColor];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
}
It looks like the view controller you are pushing from does not inherit from TTViewController. You may also need to set the 'navigationBarTintColor' property back to your original color after the view has been popped off the stack; if you have not set a global stylesheet.
Related
I implemented a custom tab bar controller as a set of buttons each one related to it's own View Controller. I guided on this link http://idevrecipes.com/2011/01/04/how-does-the-twitter-iphone-app-implement-a-custom-tab-bar/ to achieve the behavior. So the relevant part of code is as follows:
- (void) selectedItemAtIndex:(NSUInteger)itemIndex
{
// Get the right view controller
NSDictionary* data = [self.tabBarItems objectAtIndex:itemIndex];
UIViewController* viewController = [data objectForKey:#"viewController"];
// Remove the current view controller's view
UIView* currentView = [self.view viewWithTag:SELECTED_VIEW_CONTROLLER_TAG];
[currentView removeFromSuperview];
// Set the view controller's frame to account for the tab bar (+ 48)
viewController.view.frame = CGRectMake(0,48,self.view.bounds.size.width, self.view.bounds.size.height - 48);
// Se the tag so we can find it later
viewController.view.tag = SELECTED_VIEW_CONTROLLER_TAG;
// Add the new view controller's view
[self.view insertSubview:viewController.view belowSubview:self.tabBar];
//Keep track of current view controller
self.currentController = viewController;
}
So far is working, I can see each view controller in a similar maner to the default TabBarViewController. But then there's a requirement where I need to push a new navigation controller modally (it should take all the application frame) from inside one of the tabBar controllers.
At first glance I tried the following code from within one of the tab controllers:
DetailViewController *detailViewController = [[DetailViewController alloc]init];
UINavigationController *navigationController = [[UINavigationController alloc]detailViewController];
[self presentModalViewController:navigationController animated:YES];
However is not working as expected, first the view is shown below the TabBar and second the new view is not taking in consideration the parent view frame which should be the screen bounds less the tabbar. (0, 48, 360, 412). My detail view controller it's loading content from a nib file.
Well, this is quite obvious since the TabBar Controller is inserting each view below my custom TabBar.
[self presentModalViewController:navigationController animated:YES];
So I tried inserting it directly as a window subview:
[[UIApplication sharedApplication].keyWindow addSubview:navigationController.view];
But, I think this is not okay... there should be a better approach that I can't figure out. So if anybody could give me suggestions on how to correct or improve this navigation system it would be great.
Thanks a lot.
If you are building you app for iOS 5.0 and up you can make use of childViewController. In your custom Tab Bar you can have a containerView and a tabView.
The view of viewController is added to containerView. All the necessary events are generated to the subsequently added viewController if the following methods are implemented correctly
- (void)addChildViewController:(UIViewController *)childController;
- (void)removeFromParentViewController;
More about viewController containment can be found here.
How can one present a UINavigationController such that the view it was presented from is still visible in the background?
My experience is that the UINavigationController will clip anything below its view, so setting UINavigationController.view.alpha will uncover a fixed color background, not the presenting view's content.
Can this be changed?
EDIT
I am not interested in the navigation bar, but the full content the navigation controller manages.
The problem is not the UINavigationController, but the fact that you present it modally. ViewControllers presented modally can never be transparent.
You can fake a modal presentation by adding you UINavigationControllers view as a subview to the main UIWindow.
This example works for me when testing in XCode:
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [[UIColor greenColor] colorWithAlphaComponent:0.35];
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:viewController];
[[[[UIApplication sharedApplication] delegate] window] addSubview:navCon.view];
Of course you will have to do any animated transition yourself, but that should be trivial using animation blocks.
There is now a way to achieve this using the iOS7 custom transitions, this way :
MyController * controller = [MyController new];
[controller setTransitioningDelegate:self.transitionController];
controller.modalPresentationStyle = UIModalPresentationCustom;
[self controller animated:YES completion:nil];
To create your custom transition, you need 2 things :
A TransitionDelegate object (implementing
<UIViewControllerTransitionDelegate>)
An "AnimatedTransitioning" object
(implementing <UIViewControllerAnimatedTransitioning>)
You can find more informations on custom transitions in this tutorial : http://www.doubleencore.com/2013/09/ios-7-custom-transitions/
if you wish this behavior you can not use a UINavigationController, as you say the navigation controller clip the view of the content controller. To do what you want you should add a navigator bar to your view instead, and simulate the actions of the navigation controller. To create a back button similar to the controller read this article
I'm trying to add some navigation controller in my app, it's sth likes:
in my index page view controller, I try to initialize the navigation controller like this:
-(void)viewDidLoad{
...
//allocate a navigation controller.
myNavigationController = [[UINavigationController alloc]init];
myNavigationController.delegate = self;
myNavigationController.navigationBar.hidden = YES;
[self.view addSubview:myNavigationController.view];
[myNavigationController pushViewController:tabViewController animated:YES];
[self presentModalViewController:myNavigationController animated:YES];
}
Here, index page view controller is the root view controller of my app, it's just a common UIViewController here.
[myNavigationController pushViewController:tabViewController animated:YES];
The tabViewController here I've pushed into the navigation controller is a custom tabview controller which makes use of a container view to hold the tab button and also holds an navigation controller for tab switching.
The problem here is:
myNavigationController.navigationBar.hidden = YES;
since I've make the navigation bar invisible, it doesn't show when my custom view controller shows, but when I'd like to switch to some other view controller with the navigation controller and I also want the navigation bar visible:
myNavigationController.navigationBar.hidden = NO;
MyViewController *toSwitchNC = [[MyViewController alloc]init];
[myNavigationController pushViewController:toSwitchNC animated:YES];
The navigation bar would never show any more. I've also tried to put:
self.navigationController.navigationBar.hidden = NO
in MyViewController's viewDidLoad, ViewDidAppear or even in the navigation controller's delegate method, it didn't show the navigation bar neither.
So what's wrong with it? Why I initialized the navigation bar to be invisible at first, it will never show again even I set the hidden flag to be false?
Okay, I've got this fixed by removing the navigation controller container in my index page view controller. This might be a stupid question, since apple've formally stated in the developer document that the navigation view controller should be place as root as possible in the view stack. Since IOS is a closed system, who knows WTH is going on under-beneath except Apple.
I have a viewController and I am trying to add a subview to it such that it will cover the whole screen, however this has a navigationController in it so that adding a subView always adds it below the navigation bar, is there a way to simulate a presentModalViewController in cases like this?
You can add the subview to the view controller and then hide the navigation controller from the top or you could still push it to the navigation controller and then just remove the navigation controller from the top again and then you could use pop to go back and forth.
the code to push a view controller is
if(!self.YOURVIEWCONTROLLER){
self.YOURVIEWCONTROLLER = [[YOURVIEWCONTROLLER alloc] initWithNibName:#"YOURVIEWCONTROLLER" bundle:nil] autorelease];
}
[self.navigationController pushViewController:self.YOURVIEWCONTROLLER animatedLYES];
and on the next NEXTView.m add
[self.navigationController setNavigationBarHidden:YES];
remember to create an instance of YOURVIEWCONTROLLER in the .h file. Or you could do a simple
[self.view addSubview:NEWVIEW];
[self.navigationController setNavigationBarHidden:YES];
at least at bear minimum the line for making the navigationController hide is there.
I seem to recall once having a similar problem, and I seem to recall the solution was to add the subview to the navigation controller (as the view controller is already a sub view of the navigation controller) rather than adding it to the view controller.
I recently have similar problems and after spending 5 to 10 min I get the exact solution...
According to my solution I simply add my custom UIView to subview of navigationController.view
Like This :-
[self.navigationController.view addSubview:popOver];
popOver - Your custom UIView
Happy Codding :)
Add the view to the superview of the navigationController's view.
[navigationController.view.superview addSubview:viewController.view];
Perhaps you could hide the navigation bar when you add the subview. I have a method on my ViewController that looks like this:
self.navigationController.navigationBarHidden = YES;
UIView *v = [[UIView alloc] initWithFrame:self.view.frame];
v.backgroundColor = [UIColor redColor];
[self.view addSubview:v];
When that code executes, my navigation bar disappears and a full screen red view replaces it.
I'm changing the back button item title in the viewDidAppear of a controller in the following way:
self.navigationController.navigationBar.backItem.title = #"Previous";
It changes the tittle properly, but the I'm having a strange behaviour. When I select the "previous" button, it changes the tittle of the controller that is up in the stack (i.e the parent controller now has the title "Previous".
Do you now why this happened?
When you're using a navigation controller, calling [self setTitle:#"Title"]; inside of any view controller in the stack will set the navigation bar title. This is also the title used by default for the back button when you've pushed a new view controller. Apparently, from what you are experiencing, explicitly setting the title of the backItem, also sets it for the navigation bar title for the previous view controller overriding whatever what specified in the call to -setTitle in the view controller.
You will probably be better off just managing the title from within the view controllers in your navigation stack. When you go to push a new view controller, do this:
[self setTitle:#"Previous"];
NextViewController *controller = [[NextViewController alloc] init];
[[self navigationController] pushViewController:controller animated:YES];
[controller release], controller = nil;
Now, when the next view controller displays, the back button with say "Previous". Now, you just need to change it back to whatever its real title should be in -viewWillAppear:
- (void)viewWillAppear:(BOOL)animated;
{
[self setTitle:#"Real Title"];
[super viewWillAppear:animated];
}
It may feel a little hacky, but it's better than trying to override the navigation bar functionality. Wrestling with the nav bar/nav controller stack can prove very frustrating.
Best regards.