Adding Navigation Controller to existing UITableView - iphone

I'm new to both Objective-C and the iPhone SDK in general, so please bear with the noob question.
I've successfully implemented a table view with an array for the title, subtitle and cell icon and it's working out great. What I'd like to do is load a PDF file depending on which cell is selected and I understand that a Web View seems to be the best option?
I've hit a block, I can't add a navigation controller to the existing table view in the xib file (I started as a single view application) and everything that I'm reading around the interwebs is suggesting starting out in a different way. Either I'm doing something completely wrong or I've missed something entirely.
So is there anyway that I can implement this Navigation Controller and Web View with what I currently have or am I going to have to start again, copying and pasting various bits of code?
Any help appreciated.
Cheers.
Matt.

If you have a XIB file that represents a UITableView, then what you should be able to do is:
1) When presenting your UITableView:
UITableViewController *tableViewCon = ...; // Load it from the XIB file
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:tableViewCon];
// Present the navCon, however you're currently presenting your table view
2) In your UITableView, when a cell is pressed:
WebView *webView = ...; // Create the web view, and also load a URL
[self.navigationController pushViewController:webView animated:YES];

I think you need to rewrite your app. You cannot add navigation view to table view. The right pattern for your task is to start with navigation view controller as a root of your app and define your table view controller as a root controller for the navigation controller. Then, when the user selects some row in the table you should push a web view to your navigation controller.
refer for the UINavigationViewController class reference.

Related

Using the same ViewController h and m files for 2 View controllers in Story Board

So I pretty much built my first app(single view) but i've now decided I should add a little "about/info" button and just give a tiny amount of information on how to use the app and a website to go to.
I wasn't sure about the best way to go about this but storyboards seemed really convenient. A user here answered my question about adding a storyboard to my existing project which seems to work.
Now one question is can I use my current viewcontroller h and m files for the second view (the about screen). I suppose it would technically work if I set the Viewcontroller to the same one as my primary app view.
the only thing this second view is going to have is text and a button to go back. Is it OK to set the connections in the storyboard and just let them use the same Viewcontroller files or is this a big no-no?
Thanks
It is recommended you use a different view controller for each view. In case of a static view controller in which the user doesn't interact with the view except maybe for navigation (which can be handled in the storyboard in many cases), I would just leave that view controller as a generic UIViewController, not a subclass.
Yes you can use the same view controller to control more than one view, however, from what I understand, that doesn't seem like good practice in your case
For instance, if you had similar views with almost identical outlets (say the views have the same UI widgets such as buttons, titles but their layouts vary significantly) you co[uld create a separate view for each different layout and use a single view controller. But from what I understand, in your case, those two views will have different outlets (buttons, labels, etc.)
For this reason, I'd suggest creating a new view controller. Then when you want to show this second view, you will have to present it from your active view controller. I'd highly recommend you read tutorials on view controllers in Apple developer resources. But very quickly, I'd suggest the following
UIViewController *vc2 = [[UIViewController alloc] initWithNibName:#"View2" bundle:[NSBundle mainBundle]]
[self presentViewController:vc2 animated:YES completion:nil];
And to go back to your main view, you'll have to dismiss this second view controller
[self dismissViewControllerAnimated:YES completion:nil];
Of course, they don't have to be animated, you can set them to NO.

UIView should have multiple UITableViews as subview

Hi I have placed three button similar to UISegmentcontrol. But its not, its just image buttons. Here I need to have a class called MainView(UIView) and child views like Breakfast, Lunch and Dinners(UITableView for all child view). By default MainView should load the breakfast class if i click the dinner button it should take me to the dinner class. I am able to work with single tableview but I dont know how to load other classes on clicking the button from the parent class.
The child views should appear for the full screen except the navigation items. Can you please provide me you support? Thanks
Switching between multiple different views using a UISegmentedControl, similar to iCal or the AppStore application.
Follow this link: HERE
The solution in this link is hands down the best solution I've found about the issue so far. With a little bit of adjustment it also worked fine with a tabBar at the bottom.
You want to display a new view controller on your navigation controller.
// .h file
- (IBAction)dinnerButtonPressed;
// .m file
- (IBAction)dinnerButtonPressed {
DinnerViewController *controller = [[[DinnerViewController alloc] init] autorelease];
[self.navigationController pushViewController:controller animated:YES];
}
And connect your button to the dinnerButtonPressed action.
The method creates a new DinnerViewController and displays it onto your navigation controller. You can then configure the layout of the dinner view controller in it's own xib (for example, you could add a table view ...)
From your comments to deanWombourne, I understand what you want to do. To accomplish that you have to modify the datasource that your current tableView is linked to, and then reload the tableView with new datasource.
But if I were you, I would go with deanWombourne recommendation and put each of those breakfast, lunch and dinner in separate views and push them into the stack, or I would go with UITabBar and put a tableView in each.

Adding a UINavigationController to a tabbar application

I have a three view tab bar app the second view of which I want to contain a navigation controller. in the navcontroller the first/root view will be a custom uiview containing a uitableview that when you touch a cell will push another custom uiview in to disclose details about the touched cell.
I have found the documentation on doing this but it is not making sense to me or seems to be flying over my head. The docs say that you have to create the uiviewcontroller located in the navcontroller views or at least refer to them programatically. I have been using Interface builder and have become quite comfortable using it, so doing it programatically scares me a bit.
Also, This piece of code from the documentation seems troubling:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:myNavigationController.view];
}
above taken from "ViewController Programming for iPhoneOS" apple documentation
wouldn't this load up and display the UINavigationView immediately?
one problem is I dont want to display the navView immediately. the navController/stack is a secondary tab. So how and where do I impliment my navController(right now I have it instaciated in my delegate(which I think is correct)? I've been able to load up a basic UInavigationController with a navigation bar and a blank view, --minus the custom content view, through interface builder but I'm at a loss as to how to populate the custom content views.
Hope this makes sense.
Any help would be appreciated,
Nick
The first thing to understand is how UINavigationController works. It pushes UIViewControllers, not views. So, when something happens in your second tab (where the UINavigationController lives) you will push a UIViewController onto the stack.
This is typically done in:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
Which is part of the UITableViewDelegate Protocol.
So, when tableView:didSelectRowAtIndexPath is called, you need to figure out which UIViewController to push onto the stack. You can either load this View Controller from a nib, or create it programatically. Since you feel comfortable with IB, I would suggest loading it from a nib.
I would not worry about trivia like "where should I instantiate my UINavigationController?" right now. First, get it working. Then worry about where things "should" go.
It might be best to get the UINavigationController stuff working in a separate project, then fold it into your main project. This lets you ignore lots of little details while you focus on the Navigation Controller.

UINavigationController NIB requires File's Owner to have a view?

I'm having a problem setting a View Controller nib's default View Outlet in Interface Builder. Here's my setup:
I have a TabBar based application where I load a Navigation Controller as a modal view...
MyNavCtrlrSubClass *menu = [[MyNavCtrlrSubClass alloc]initWithNibName:#"MenuController" bundle:nil];
[tabBarController presentModalViewController:menu animated:anim];
MenuController itself is structured as follows:
MenuController.xib
File's Owner (MyNavCtrlrSubClass : UIViewController)
Navigation Controller (UINavigationController)
Navigation Bar (UINavigationBar)
Root View Controller (Nib Name is set to load AnotherViewController.nib)
Navigation Item -> (UINavigationItem)
This all works fine, except that when MyNavCtrlrSubClass is loaded, I get the following error:
Loaded the "MenuController" nib but the view outlet was not set
It's clear why this is happening - File's Owner doesn't have an outlet connection for its view. The question is what should I set as its view, and does something have to be set in the first place? The Navigation Bar is the only candidate in MenuController.xib, but doing this will just size the UINavigationBar itself to the fullscreen mode, so to speak.
I'm obviously missing something in IB, but what? MyNavCtrlrSubClass.m has no code itself, except an IBOutlet for the UINavigationController. Am I making a mistake trying to set this up entirely in IB? The idea is to keep the modal Navigation Controller in one nib, and all the views it loads in separate nibs, but since MenuController is just a container for the navigation and contains no views itself, I'm obviously designing it wrong. :)
If you're wondering why I'm not designing it some other way, it's because I'm trying to obey my (possibly mistaken) perception of how IB asks you to build an ideal hierarchy.
Any help would be greatly appreciated.
I think you might not be understanding how the File's Owner is meant to be used in a NIB file. I've written up a response describing the file's owner under another question.
When you invoke this line:
[[MyNavCtrlrSubClass alloc] initWithNibName:#"MenuController" bundle:nil]
You create an instance of MyNavCtrlrSubClass, and tell it to load #"MenuController". Then in the MenuController.xib file, there is a second unrelated UINavigationController with things inside of it. When MenuController.nib is loaded at runtime, that second navigation controller will be created.
A second problem is that telling a UINavigationController to load a NIB file isn't really sensible because navigation controllers create and manage their own views. You really want to create the root view controller, and tell that view controller to load a NIB file.
Try this:
MyRootViewController *rootController = [[[MyRootViewController alloc] initWithNibName:#"AnotherViewController" bundle:nil] autorelease];
MyNavCtrlrSubClass *menu = [[MyNavCtrlrSubClass alloc] initWithRootViewController:rootController];
Where your XIB File looks like this:
File's Owner (Class set to MyRootViewController, view outlet connected to subsequent UIView)
UIView
Subview A
Subview B
After you're confortable with how all of this is working, you might also consider instantiating the navigation controller and root view controller in one XIB file like you were starting to do in the code you posted.
The crux of this question is stated by Travis himself: "How would you load Navigation Controller nib, designing as much as possible in Interface Builder?" And also from the example, it looks like this means the UINavigationController and associated UIViewControllers.
With this interpretation, the answer is you cannot fully configure a UINavigationController and it's UIViewControllers in a single XIB. Yes it is intuitive to want to do this so you are not crazy.
When I say you cannot do this, I mean the most commonly used framework methods do not have a way to handle this. There is no [UINavigationController alloc] initWithMegaNibName. Yes you could stuff almost anything in a single XIB and write code to hydrate objects in special ways, but I don't think that's what you're looking for.
You could use two or more XIBs as Jon suggested, but then things are less self contained and so you have many folks who find it simpler to do part, or all, of the controllers in code.
Unfortunately there is not a 1:1 correspondance between Interface Builder capability and code like there is on other dev platforms. I generally prefer to be able let designers participate as much as possible in creating assets, but most of them I know do not code objective-c.
In IB, in the MenuController nib add a UIView and set that view as the outlet. You will need to set that view for a UIViewController. Here is a quick link to an Apple page showing a basic setup. Not sure if it will help you at your current stage though.

How to use UISearchDisplayController from a controller within an UITabBar controller?

I have an UITabBar controller managing several controllers (using SDK 3.0). One of these is a tableView controller and I need to provide a search capability using the UISearchDisplayController. All of my code is based on Apple TableSearch example. However, when clicking on the tab, the tableView controller appears showing its related content, but no searchBar appears. I have checked the xib in IB to make sure that all of the outlets are properly set, but no matter what I try self.searchDisplayController is always nil and the search bar does not appear.
In practice I have replicated MainView.xib from the TableSearch example and set the file's owner class to the correct controller class for the tab. The outlets are sets as in the example MainView.xib. Am i missing any important step or doing something wrong?
Thank you in advance.
I had the same issue and happened to stumble upon this solution ...
If you have your table view controller (eg. UISearchDisplayController) nested in a Tab Bar or Navigation controller using Interface Builder, you need to set the "Nib Name" in the "Attributes Inspector" window.
The Nib name will be the one that holds the table view and has the controller (eg. UISearchDisplayController) as the File's Owner.
I too have this issue :( Is the search bar getting hidden behind the tableview?
#unforgiven,
did you try this...?
searchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, 320, 40)];
[self.tableView setTableHeaderView: searchBar];
This manually creates a searchbar and it works. But I'm making some stupid mistake in IB that the SearchBar doesn't show up even though my connections are perfect. :-(
Do update this post if you get the answer...
Ok, I have found how to solve it. In my case, the problem was due to the fact that I was using a controller embedded within the UITabBarController as one of its managed tabs (i.e. as a child).
Removing the controller from the UITabBarController, then adding an UINavigationController to the UITabBarController instead, and finally putting my controller as a child of the UINavigationController solved completely the issue.
I do not understand why this is so (there is no related information in the documentation, as often happens); however, it now works like a charm.
With kind regards.
I had a similar issue
To solve I had to do one additional step to unforgivens answer
In my main nib
1) create a UITabController
2) Then I dragged out a UINavigational Controller into the tab controller
3) Then dragged out a UITableViewController into the NavigationalController as a child
4) Then changed (3) class to be my MyTableWithSearchBarViewController in the inspector - check if the nib name is correct and change this if necessary in the inspector as well
5) I then had to delete the tableView which is automatically created by IB in step (3). Only then would the search bar show correctly...
If in step 3 I dragged out a different controller onto the stage or left the tableView there it would only ever display the table and not the search bar
weird
Tomtrapeze has the right answer if your nib file contains the UITableViewController. But, if you're loading the UITableViewController in code -- such as pushing it on the stack of a UINavigationController -- the solution is a little different.
When initializing the UITableViewController or subclass, you need to use the -initWithNibName:bundle: form of initializer and specify the name of your nib file. Alternately, you could use the standard -initWithStyle: initializer and manually set the nibName property before the view is loaded.
If the nibName property is not set when the view gets loaded, UITableViewController will not use the normal UIViewController nib lookup logic. It will just load a standard UITableView instead.
I recently learned that I could load NIB files with [[MyViewController alloc] initWithNibName:nil bundle:nil]; when the NIB file has the same name as the class (i.e. MyViewController.xib). It turns out that initializing this way causes the 'UISearchBarandUISearchBarDisplayController` to not display. When I initialized the view controller by actually typing out the name of the class, my search bar showed up correctly. I initially thought it had something to do with how I was presenting the view controller but was glad that it wasn't.
PGWSearchViewController *searchVC = [[PGWSearchViewController alloc] initWithNibName:#"PGWSearchViewController" bundle:nil];
searchVC.modalPresentationStyle = UIModalPresentationFullScreen;
searchVC.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:searchVC animated:YES completion:^{ }];
This is using iOS SDK 5.1 and XCode 4.3.1.
Another possible fix that works for me is to init the UITableViewController with initWithNibName:bundle:
SearchEntryTableViewController* searchEntryTableViewController = [[SearchEntryTableViewController alloc]initWithNibName:#"SearchEntryTableViewController" bundle:nil];
To nest the UITableViewController in a UINavigationController before put it in a UITabBarController doesn't fix the issue for me...