Navigation Bar + presentModalViewController - iphone

I have a navigation bar based application, and at one specific point in the app I have a button on the nav bar that should present a new view using a flip transition (essentially taking a user from a tableview to a map view). I'm currently using
DetailLocationView *detailLocationView = [DetailLocationView alloc] init];
detailLocationView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self.view presentModalViewController:detailLocationView animated:YES];
[detailLocationView release];
This code takes the entire view the user is in (navigation bar and table view) and flips it into just the detailLocationView. However, I would like for the detailLocationView to still have a navigation bar. I'm wondering what the best way to have the detailLocationView be loaded in so that it has a flip transition and is still has a navigation bar.
Thanks

pushViewController instead of presentModalViewController will retain the navbar, but will not as you want.
If you want to "flip" and still have the Navbar - you'd have to flip to a new view with the navbar. This is sort of illogical though, from a UI perspective - i.e. when you visually see the view flip - you're seeing it change to something completely different - so for the view to flip and then reveal the same navbar may be a bit confusing.

Related

Having more than 1 navigation controller in an app

I've been requested to mock up an app with the following design.
The large gray box is the main view area. (UIView)
The 2 pink squares are buttons. They are almost like tabs of a tabbar in how they should function.
What I am struggling to achieve is to get 2 UINavigationbars/Controllers to appear in the UIView(large gray box) when a button is pressed. Not at the same time of course, but which ever Navbar/Controller/View that is shown is dependent on what button was selected.
I can make a UIViewControllers view appear there ok by doing the following
TabViewOne * vcTab = [[TabViewOne alloc] initWithNibName:#"TabViewOne" bundle:[NSBundle mainBundle]];
[self.mainView addSubview:vcTab.view];
That makes the view of TabViewOne appear in my mainView area (gray box).
What I would actually like to happen is that I can get my view to appear here but with a navbar and all the functionality that it brings. I will eventually just hide the nav bar but use its functionality to move up and down the view stack.
This is what I tried to get it working but the view stays blank when I try this :
TabViewOne * vcTab = [[TabViewOne alloc] initWithNibName:#"TabViewOne" bundle:[NSBundle mainBundle]];
UINavigationController * navVC = [[UINavigationController alloc] initWithRootViewController:vcTab];
[[navVC navigationBar] setHidden:YES];
[self.mainView addSubview:navVC.view];
Could somebody please advise me how to do this properly?
Many Thanks,
-Code
You can achieve your requirement from a small trick. You can implement a tab bar controller there. In tab bar controllers each tab can be run inside a separate navigation controller. In the root view controller of both the tab items you have to have that 2 button design. If you use a generic view and add it as a subview you can easily reuse it. Next thing is it will appear the tab bar at the bottom of the view as you have a tab bar controller there. You can hide it simply by making its frame rectangle to a non visible position. After that your tab selection should be done manually based on the users button click.

Navigation Issue with UITableView

How do I navigate back to the previous page with a UITableViewController. I tried to show a navigation bar with navigation button at the top of the screen, but the navigation bar will not show. I know that you have to give the previous view a title but when I go to do that it does not show anything. Also, since it is a UITableViewController I am not able to drop a navigation bar and add a button to the main view. All I would like to do is display my lists and have the option to navigate back to the previous list with a single button in the upper left corner.
The problem you having with the NavigationController is that your tableViewController is not in the NavigationController hierarchy. Want you want to do this when adding the tableViewController:
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:yourTableViewController];
Then you can do this to add yourTableViewController:
[self.view addSubview:navigationController.view];
If you don't want the navigationBar to appear on the tableViewController just use:
self.navigationController.navigationBarHidden = YES;
in yourTableViewController viewWillAppear method.
When your going to add the view after the tableView you just use:
[self.navigationController pushViewController:someViewController animated:YES];
It's not enough to give the child view a title. You need to give the child view's navigation item a title before you present it. For example, in the parent view, before you push the the view to the navigation stack, do something like this...
[MyChildView.MyNavigationItem setTitle:#"A cool Title"];
For the navigation you are trying to achieve you should be using a UINavigationController. It already has the functionality you describe with the navigation bar and back button built into it.
To move to the next screen (which can be a UITableViewController) you use pushViewController:animated: and to move to the previous screen you use popViewControllerAnimated: (although the built in back button will do this for you).
I suggest reading the UINavigationController class documentation if you are not already familiar with it.

View sizing with setting navigationbar to hidden with push/pop

So before I push a new viewController onto the stack in a certain view, I set the navigationBar to hidden I notice that it disappears before the next screen gets pushed and the slide animation happens (because I need a UIToolbar at the top).
So question #1: is there a way to push a new view controller and setting the navigationbar to hidden, and not getting the hide animation until after the new view controller is on screen. it looks funny that the navigation bar hides then pushes the new view controller.
Once the new view controller is present, when I pop it off, I set the navigation bar back
[self.navigationController.navigationBar setHidden:NO];
But when it is popped, the navigationbar is not back any more. Is it because this navigationBar is for the current navigationController and not the new one that is being presented after the pop? (question #2)
Question 3: Realizing it isn't showing my navigationBar, in the viewController that gets presented after the pop, in its viewDidAppear, I added
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.navigationController.navigationBar setHidden:NO];
}
which shows the navigationBar, but the view size is incorrect since it seems like once the navigation bar was hidden, the rest of the view took up the empty space, and then the navigationBar is on top of the content. Is there anything I can do about this? Or am I approaching it incorrectly with push and pop?(question #3).
Thanks!
I was running into the very same problem (only in reverse: I was starting from a NavigationBar being hidden and pushing a view where I wanted the NavigationBar visible), and there's actually an extremely easy fix.
Simply replace your calls:
[self.navigationController.navigationBar setHidden:NO];
with
[[self navigationController] setNavigationBarHidden:NO animated:YES];
In my code, I call these statements in the - (void)viewWillAppear:(BOOL)animated methods of each respective View Controller.
I just tried this solution in the order you are using (visible, then hidden), and it seems to work just as well.
Interesting issue. You could try changing the hidden property in viewWillAppear and viewWillDisappear, but it seems like that might not give the desired results either.
Can you present the view controller modally instead of making the navigation bar disappear? If it's the last view controller on the stack, that would be possible. It might also make more sense to the user to see a view controller presented differently. This might indicate to the user that navigating away from this view controller is no longer done with the Back Button. It could be more reasonable than having the navigation bar just disappear.
If you still wanted the view controller to slide in from the right, I don't think it can be done with a modal view controller. But, you could do that by animating a view that fills the screen. (You just add the view with a frame that has origin.x equal to the width of the screen. Then, in the animation, you change origin.x to 0.0. Let me know if you need more detail on this.)
However, I would recommend presenting the view controller in a different manner from the way a view is generally presented by a navigation controller. Because, essentially, you are no longer letting the user navigate away from this view as he/she generally would from within a navigation controller. (So, my response to question #3 would be 'yes'.)

switch views using a button, going to a table view, iphone

My program has 4 buttons and each button calls a different table view. That works fine, but my problem is, the view controller I'm using brings up a table view that covers up my navigation bar and my tab bar. I need to replace that coding with something that will bring up a table and not cover up my nav and tab bars. Here is the coding I'm using:
-(IBAction)buttonNorthWest {
NorthWestViewController *nwController = [[NorthWestViewController alloc] initWithNibName:#"NorthWestView" bundle:nil];
self.nwViewController = nwController;
[self.view insertSubview:nwViewController.view atIndex:0];
[self presentModalViewController:nwViewController animated:YES];
[nwController release];
}
The [self presentModalViewController....] is the problem. Does anyone know how I can replace that code with something that keeps my nav and tab bars?
Thanks,
Jaime
On the iPhone, all modal view controllers must be full screen as seen here http://developer.apple.com/iphone/library/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle
As an alternative you could display the tableview as a subview and adjust the frame so that it does not overlap the nav or toolbar.

Presenting modal view occasionally hides the navigation bar

I've come across this twice now.
Sometimes using the following line of code:
[self.navigationController presentModalViewController:aViewController animated:YES];
displays the view, but the navigation bar is then hidden.
I can write:
[self.navigationController setNavigationBarHidden:NO];
to my hearts content, everywhere I can think of with no effect.
Has anyone ran into this?
Am I doing something silly?
No, I ran into this as well. The problem is that when you present a modal view controller with a UIViewController based class, it does not extend the calling navigation controller's nav bar onto the modal. The modal view covers the entire screen. What I ended up doing to solve the problem was to create a UINavigationController and push the UIViewController based class onto it, and then do presentModalViewController to the navigation controller's instance.
like:
UIViewController *vc = [[UIViewController alloc] init];
UINavigationController *cntrol = [[UINavigationController alloc] initWithRootViewController:vc];
[self presentModalViewController:cntrol animated:YES];
[cntrol release];
That allowed me to have a nav bar at the top.
I am not sure if that will help in your particular case, the only other thing I would suggest is to replicate the behavior of the modal with a UIAnimation that stops 44px below the top of the phone. That would keep the original navigation bar visible.
#HeatMiser shows a great way to get around the "bug" surrounding the inability to display items on the nav bar. I'm not sure, however, if this is strictly a bug in Presentation, since modal operations ought to trump the underlying view's interface theme. Having the modal operation's theme mimic the underlying UI theme is fine, but wrapping the true modal view with a navigation view feels wrong to me (extra view object just to get a little more behavior).
Instead, the following worked for me and gives the same behavior as "New Message" does in the Mail program (on the iPhone).
In IB, place a UIToolBar at the top of the modal screen (mimicking the navigation bar) with "Cancel" and "Save" UIBarButtonItem's and a Flexible Space Bar Button Item in between to get the buttons to align left and right. Then, add a UILabel centered over the UIToolBar (The Font Helvetica, Bold, Size 18 appears to match the Navigation Bar Title). Connect the buttons to IBAction's on the modal's UIViewController, and you're done.
If there is a navigation controller active, then you should just use
[self.navigationController pushViewControllerAnimated:how];
to slide another view controller in, while giving yourself and the user into a consistent user interface complete with 'automatic' back button support.
Once a navigation controller is in use, presenting a modal view controller should only be done to enlarge the usable area on the screen. And then, you should really use a fancy animation to let the user know that you are stepping away from the "task" or "steps" that the navigation controller was embodying.
Maybe this is obvious, but once you're done with the modal view and want to dismiss it, you should do something like this in your modal vc:
[parentController dismissModalViewControllerAnimated:YES];
Where parentController is a reference to the vc from where you are presenting the modal view.