iPad: Merge concept of SplitViewController and NavigationController in RootView? - ipad

I'm having trouble merging the two concepts of using a SplitViewController in my main view and having the "RootView" controller that controls the left panes popup/sidebar table view.
I want to have the left "RootView" act as a navigation menu, but how do I do this when the RootView is tied through MainWindow.xib into the left pane of the SplitView?
Basically, I want the left navigation to work just like the built-in email applications folder drilldown navigation. Is there an example iPad project out there that uses both SplitView and a NavigationView for the left/Root pane?

After you create a SplitView project, open up the RootViewController.m file and look at the -tableViewDidSelectRowAtIndexPath method. You'll see that the item that you clicked is then set as a property of the DetailViewController.
The design you're looking for would require that you push another view controller onto the navigation stack. So if you imagine the e-mail application, when a user picks a folder, the detailView is not updated, but the next level of the Inbox is pushed onto the stack. When a user selects a message from the inbox, the detail view is updated with the message contents, and the RootViewController just stays where it's at.
in the -tableViewDidSelectRowAtIndexPath method, declare your new view controller
NextViewController *nextView = [[NextViewController alloc] initWithStyle:UITableViewStylePlain];
//This assumes you have another table view controller called NextViewController
//We assign it to the instance variable "nextView"
[self.navigationController pushViewController:nextView animated:YES];
//tells the navigation controller to "slide" the "nextView" instance on top
//if animated:NO it wouldn't slide, it would just "update"
[nextView release];
//release the viewController, it's now retained automatically by the NavigationController
Does this make sense?

Related

How do I connect a TableViewController to my main ViewController?

Right now I have:
TableViewController - displays a table that is populated with images and has UITableViewDelegate methods
ViewController- empty except for default viewDidLoad() fn
When I run my program, the screen is blank, presumably because my ViewController has nothing in it.
How do I make it so that it displays my TableViewController?
I have a hunch that I should use prepareForSegue, but am confused because when does prepareForSegue ever get called? I've read it is called before the viewDidLoad(). In that case, should I add a prepareForSegue function in my ViewController that directs to my TableViewController?
Click the ViewController in your storyboard, delete it, and then select your table view controller in the storyboard (click the little yellow icon on the left where the three icons appear right above the controller so that there is a blue outline around the controller). In the Attributes inspector in the utilities panel on the right in Xcode, check "Is Initial View Controller". Sounds like you don't need the other view controller at all.
If you want to segue to the table view controller from your view controller, add a button or some other UI control to the view controller, control-drag from that control to your table view controller, and then select a segue type. prepareForSegue() is called right before segueing; it's a way for you second view controller (in your case your table view controller) to get data that it may need from the first view controller.
You can set the root view controller in the app delegate didFinishLaunchingWithOptions method. Something like:
TableViewController *tableViewController = [[TableViewController alloc] initWithNibName:nil bundle:nil];
self.window.rootViewController = tableViewController;
[self.window makeKeyAndVisible];
should do the trick.

Does the navigation controls and other controls have to be within the appDelegate?

Is it possible to start your project with a single view controller, then on the second or third view controller implement the navigation controller, then maybe on the forth view controller implement the tab view controller? Or does this type of project need to be a storyboard project?
My dilema at the moment is that I start with just one single view controller that has a round rect button that takes you to the second view controller. From the second view controller, I would like a navigation controller with an embedded table view that will take me back and fourth from the second to the third view controller. I've been trying for hours putting the necessary code into each .h and .m file but I keep hitting brick walls.
Thanks in advance.
a. You can of course present several regular view controllers then add a UINavigationController at a later stage. When you need to present the navigation controller, you can embed your detail view controller inside one as follows:
(code is in the view controller which you want to display the detail view controller from)
DetailViewController *detailVC = [[DetailViewController alloc] init];
UINavigationController *detailNav = [[UINavigationController alloc] initWithRootViewController:detailVC];
[self presentViewController:detailNav animated:TRUE completion:nil];
b. It is not allowed to have a UITabBarController inside a UINavigationController (or any other view controller). You can however still use the UITabBar control and manage the rest. For an example of this, please refer to UITabBarController inside a UINavigationController.

UISplitview with UITabBar behavior

I have moved from UITabBar to split view on my iPad application.
The view controllers are sent by the master to the detail which puts them into a UINavigationController.
// Detail manager called when a cell is selected on the master
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:_detailViewController];
UIViewController *mainNavigationViewController = [self.splitViewController.viewControllers objectAtIndex:0];
NSArray *viewControllers = [[NSArray alloc] initWithObjects:mainNavigationViewController, detailNavigationController, nil];
self.splitViewController.viewControllers = viewControllers;
Now every time a cell on the master is selected, the navigation controller on the detail view starts from the root.
Instead I would like to have the same behavior of the tab bar controller: when you move from one tab to another, the navigation stack for each tab is maintained. And when you select two times the same tab, the navigation stack pops to the root view controller.
How to implement this in a proper way with a split view based application?
You should make a navigation controller for each cell in the master table. When tapping a cell, you switch it accordingly. If the selected cell is tapped, you call popToRootViewController:animated: on the visible navigation controller. Of course, you have to subclass UISplitViewController to keep a reference to your navigation controllers. You would also have to create a MaterTableDelegate to tell you split VC, he should change the navcon in the detail side.
Starting from the suggestions of Levi I implemented a working solution.
To summarize:
Subclass UISplitViewController
Create on it a public reference to each UINavigationController you need
Inside the init of your UISplitViewController subclass initialize all the navigation controllers with their respective root UIViewControllers
According to your master-detail implementation, make sure that every time you select a cell in the master view, the right navigation controller (among all the one you have declared on your UISplitviewcontroller subclass) is presented on the detail view. I managed this with an NSinteger property on the detail manager (set on master cell selection) to tell it which navigation controller to present on the detail view.
If the same master view cell is selected twice, pop the corresponding navigation controller to root to simulate the same UITabBar behavior.
Hope this will help someone.

UINavigationController isn't pushing/displaying view

New to iOS and objective C. Trouble with custom UINavigationController while developing an iPad app in XCode simulator. Appreciate your help greatly !
Created project (view based application) in XCode. Application currently has two views. Home Page and a Detail View. Want a Home Page like Facebook or Linkedin iPhone App Home page...where you have bunch of icons/images on the home page, and click on each to get more details
(With limited knowledge) concluded Home page can't be TableView, SplitView or TabBarView. Don't want any tabs or table view style in Home page (as explained above). So couldn't start XCode project with "Navigation Based Application" template
Didn't add UI elements from IB to MainWindow.xib, rathar homepage UI elements are in the otherView.xib created by the project template. The project template, assigns rootViewController to otherViewController within appDelegate.didFinishLaunchingWithOptions method. self.window.rootViewController = otherViewController.
Added a NavigationController through IB to otherView.xib. Added outlet for navigationController. otherView.h has following
UINavigationController *navigationController;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
referencingOutlet for navigationController is connected to File's Owner
When App is launched Home Page (served by otherViewController) comes up. When clicking on an icon in Homepage (an ImageView with Button behind), Detail View doesn't show up, if I call
[self.navigationController pushViewController:DetailViewController animated:YES];
(within the action method, that's handling touchUpInside for that button.)
but detail view shows up if I do either
self.view = DetailViewController.view;
or
[self.view addSubview:DetailViewController.view];
So doesn't seem to be a problem with DetailView loading it's nibfile etc.
No problem also in button click/touch event capture etc.
A. When I examine the navigationcontroller in the debugger, it has both the two viewControllers in its stack, with rootView/ Home page at index 0, and Detail View at index 1. navigationController is not null. Any ideas on what am I missing ?
B. Do I need to add a navigationBar to both the home page (in whose view navigation controller is added) and the detail view ? I have added a navigationBar to the detail view. I don't need a navigation bar in the home page UI.
C. When the detail view shows up through the addSubview call or self.view assignment (as mentioned above), the navigationBar doesn't show the back button (which should say "Home").
Both view Controller is setting appropriate title , using self.Title = "Home" or "Detail".
Appreciate your help. Thanks
In the appDelegate, you need to make navigation controller a property and then write:
self.window.rootViewController = self.navigationController;
in application didFinishLaunchingWithOptions: method.
Then push otherViewController onto its stack. I think the mistake you're making is adding UINavigationController to UIView instead of the other way around, which is the correct way!
what you should do too in your xib file,
make sur that you view is in a navigationcontroller
the tree of your xib file should like this :
your appdelegate
window
navigation Controller
navigation bar
and your rootviewcontroller

TableViewCell disappears when push UINavigationController in UITabBarController's More tableview

I add 6 navigation controllers to UITabBarController's viewControllers. As normal, a More tab is created to list the last two. The problem is: after I select a table cell in the More table view, that cell's content fade out and disappear before the view controller push in. And then, after I back to the More table view by click the Back button, that cell's content show again. I guess the reason is More table view in its own navigation controller, and it push another navigation controller (created by me). I don't want to remove my navigation controller because I want to allow user rearrange tabs using the UITabBarController's Edit function. Can anyone suggest what I should do?
Create instances of your 6 navigation controllers in AppDelegate and retain them. And release in dealloc method
Just had the same problem. In my case I accidentally assigned the tabBarItem to the VC inside the navigation controller. When I instead initialized the tabBarItem on the navigation controller, the flickering / disappearing stopped.
MyViewController* viewController = [[MyViewController alloc] init];
UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:viewController];
[viewController release];
// this has to be navigation.tabBarItem (not viewController.tabBarItem)
[navigation.tabBarItem initWithTitle:#"Title" image:[UIImage imageNamed:#"fancy.png"]
tag:42];
Initializing the tabBarItem on the viewController still showed the icon which made it harder to discover. I'm also not very sure (actually I think it's bad) about the way I initialize the tabBarItem (without alloc). But I had troubles with disappearing icons etc and hey, it works ;-)

Resources