Adding detail view to UITableView - iphone

This app is my first app using a UITableView, and I've run into issues why trying to add a detail view to it. (because I made my app a "View-based Application" when I first created it, I have to do this manually).
This is the code for my didSelectRowAtIndexPath: of the table view:
detail = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle: [NSBundle mainBundle]];
detail.delegate = self;
detail.dtitle = [titles objectAtIndex: indexPath.row];
detail.dusername = [usernames objectAtIndex: indexPath.row];
detail.dpassword = [passwords objectAtIndex: indexPath.row];
[self.navigationController pushViewController: detail animated:YES];
//[self presentViewController:detail animated:NO completion:nil];
The second to last line is the one causing problems. I copied it from a blank "Master-Detail Application" that I made, but it doesn't seem to work in this app as it does in the other. The commented out line is what I've been using in it's place, but isn't exactly what I want.
What can I do to fix this?
Secondly, in theDetailViewController, the back button in my title bar (the navigation item of a navigation bar, to be precise) just will not appear. Is there code I have to add to indicate that this view is a subordinate view or something?

In order to push another view controller using the nav controller, there actually needs to be a navigation controller. Is "self" in a navigation controller?
If not, create a navigation controller setting its root view controller to the first view controller. If the first view controller is your app's root view controller, now make the navigation controller the root view controller instead.
Once that is in place you can call [self.navigationController pushViewController: detail animated:YES];.

Related

How to push DetailView without NavigationController on UIViewController

I have a ViewBased App. I added a UITableView on one of the UIViewControllers. It shows the data and I implemented all the delegate methods etc. My problem is when I want to show the detailView it just doesn't happen. My code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *detailViewController =[[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
NSLog(#"DidSelectRowAtIndexPath");
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
I see that I need a navigationController but I don't have one and I was unsucessful trying to add one programatically. I don't have one in my appDelegate either, so my question is do I need to add one to show the detail view? If yes, please give me a code sample how to do that.
If not, what other way is there?
I am new to iOS so I am a bit lost here.
Please help!
To add a navigation controller programmatically just for this detail view, you need to something like this:
UINavigationController * controller = [[UINavigationController alloc] initWithRootViewController:detailViewController];
[[detailViewController] release];
[self presentModalViewController: controller animated: YES];
If you want to use pushViewController, you need to already have a navigation controller surrounding the view you're starting with.
You need to add the Navigation Controller FIRST, then your master table becomes the root view controller of the nav controller, then when you tap a row in the table, you push another view controller onto the nav stack.
How does your master table get into the app in the first place? If you're using a nib, it's super easy to just change out the view controller for a nav controller with the old view controller added as a child of the nav controller.
You can create one programmatically by working within your app delegate's application:didFinishLaunchingWithOptions: method like so:
UITableViewController *tableViewController = [[[WhateverYourSubclassVCIsCalled alloc] init] autorelease];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
window.rootViewController = navController;
[window makeKeyAndVisible];

Pushing a new view on a navigation controller from a cell's view controller

I have a navigation view controller which navigates between some tableviews and I've just added an "edit" button inside the cells of one of the tables. What I'd like to happen is for the user to tap the edit button inside the cell and for the navigation controller to shunt across a new view where all of that cell's content is laid out for easy editing.
The cell, however, has no access to the navigation controller and cannot push a new view controller on to its stack. How can I do what I want?
Note that I am not using segues and storyboards as it's an old app and I want to continue supporting devices running iOS 4.
You should set the target of the button to the UIViewController that is already on the stack?
If you don't want to add this new view to the Navigation (Stack), Simply use the PresentModalViewController
// In action method for edit button
- (void)editButtonClicked {
EditViewController *editViewController = [[EditViewController alloc] initWithNibName:#"EditViewController" bundle:nil];
[self.navigationController presentModalViewController:editViewController animated:YES];
[editViewController release];
}
I'm not sure if you want this, but you can try:
// In action method for edit button
- (void)editButtonClicked {
EditViewController *editViewController = [[EditViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:editViewController animated:YES];
[editViewController release];
}

iOS Jump to different view

I have a navigation based app. The root view is a list of items. From this root view you can tap on a table cell to an item's detail view. Or you can go to a form view to create a new item via the 'Add' button in the nav bar.
My question is how I can jump from the form view to the detail view once the new object has been created?
I don't want to push the detail view on top of the form view, because I want the root table view to be what the user see's after pushing the 'back' nav button form the detail view.
I've tried the following. It pops to the root view fine, but doesn't push the detail view after that..
[context save:&error];
[self.navigationController popToRootViewControllerAnimated:NO];
// display detail view
GoalDetailViewController *detailViewController = [[GoalDetailViewController alloc] initWithNibName:#"GoalDetailViewController" bundle:nil];
// Pass the selected object to the new view controller.
detailViewController.goal = goal;
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
Any help and direction would be much appreciated :)
Cheers!
Generally you would implement the add button using a view controller displayed modally.
[self presentModalViewController:modalViewController animated:YES];
meaning it appears from the bottom of the screen (see adding a contact). Then when they press done in the top right you can push the detail view controller on the navigation controller without animating it, making the back button go back to the original list view.
This isn't something you see too often in apps, but it can be accomplished like this:
// Get the current view controller stack.
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
// Instantiate your new detail view controller
GoalDetailViewController *detailViewController = [[GoalDetailViewController alloc] initWithNibName:#"GoalDetailViewController" bundle:nil];
detailViewController.goal = goal;
// Remove the topmost view controller from the stack
[viewControllers removeLastObject];
// Replace it with the new detail view controller
[viewControllers addObject:detailViewController];
// Change the view controller stack
[self.navigationController setViewControllers:viewControllers animated:YES];
// Clean up
[detailViewController release];
Exactly what animation you get is described here.

UINavigationController, UITableView and not showing the next view

I am having a problem with a table and showing another view when the user touches a table cell. I am using a UITabBarController for the main view to show different views. I then use a UINavigationController when the user selects a UITableView view to display the next view from the table cell selection.
My problem is this: when they select the table cell, the cell is highlighted and the next view does not appear. I am using IB. All of the examples I have found are doing this the same way I am, except the examples work!
I have the controllers loaded in a NSMutableArray with a Dictionary. I also tried this code by directly creating a view controller rather than using the array item. Same results....
I checked the target controller (Calc1ViewController) to make sure there was nothing wrong with the controller. When showing it directly, the controller (Calc1ViewController) displays correctly.
Here is some code.....
The initialization of the view controller in the dictionary:
Calc1ViewController *calc1ViewController = [[Calc1ViewController alloc] init];
[menuList addObject:[NSDictionary dictionaryWithObjectsAndKeys:
NSLocalizedString(#"SSC - page 1",#""), #"title",
calc1ViewController, #"viewController",
nil]];
[calc1ViewController release];
I also tried this without using the dictionary -- creating a view controller in place of the [[menuList objectAtIndex:...]; line -- by creating the view controller like this:
Calc1ViewController *targetViewController = [[Calc1ViewController alloc] init];
// the table's selection has changed, switch to that item's UIViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIViewController *targetViewController = [[menuList objectAtIndex: indexPath.row] objectForKey:#"viewController"];
[[self navigationController] pushViewController:targetViewController animated:YES];
targetViewController = nil;
}
The navigation controller is defined in the AppDelegate and connected to the RootViewController through IB.
When I select a table row, it shows in the debugger that the pushViewController code is executed, but the next view does not show. Here is an example:
alt text http://thecoolestcompany.com/ssc-table-view.jpg
Any ideas?
Finally figured it out......
I had the UINavigationController and the UITabBarController on the same level. After moving the Navigation Controller as a child to the tab bar controller, everything worked. You may add as many navigation controllers to a tab bar as you would like. In IB is is a little confusing. You need to drag the NavigationController into the TabBar to as it as a new Tab Bar item.
Theres not much to go by with t he code you have provided. Only thing i can think of without looking at more code is that perhaps you have not initialized your view controller (the one in your dictionary) correctly, or at all, or the dictionary you are accesing there is not the correct one...
What is the value of [self navigationController] when pushViewController is called. Is it nil?
What is the value of targetViewController when it is passed to pushViewController. Is it nil?

Navigation Based Application with TabBar

I have a Navigation-Based Application that shows a TableView where you can select a cell and it brings you to a "Detail View" for that cell. I want this view to then have a TabBar where I can select between 3 subviews. I have found several solutions online for this but none are very helpful. Is there a tutorial for this specifically or is their source code indicating how it can be done? Thanks
Basically What you need to do is push a Tab View Controller onto the Navigation Controller's viewcontroller stack.
Starting with a fresh "Navigation-Based Application" template. I added the following method in RootViewController.m :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Navigation logic may go here. Create and push another view controller.
UIViewController *viewOneViewController = [[UIViewController alloc] init];
viewOneViewController.title = #"One";
viewOneViewController.view.backgroundColor = [UIColor redColor];
UIViewController *viewTwoViewController = [[UIViewController alloc] init];
viewTwoViewController.title = #"Two";
viewTwoViewController.view.backgroundColor = [UIColor orangeColor];
UIViewController *viewThreeViewController = [[UIViewController alloc] init];
viewThreeViewController.title = #"Three";
viewThreeViewController.view.backgroundColor = [UIColor greenColor];
UITabBarController *anotherViewController = [[UITabBarController alloc] init];
anotherViewController.viewControllers = [NSArray arrayWithObjects:viewOneViewController, viewTwoViewController, viewThreeViewController, nil];
[self.navigationController pushViewController:anotherViewController animated:YES];
[anotherViewController release];
}
Changed this to 25 to test:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 25;
}
Now when I build and run I'll see what you are looking for in a basic way. What you will want to do after you get this working is to change the UIViewControllers to Custom Subclasses that you create to hold the code for each view. (If you are also using Interface Builder, change the init to initWithNibNamed:).
Hope this helps you get on your way a bit.
You should be aware that it's possible Apple will reject your application if you do this though.
From "Combining Tab Bar and Navigation Controllers"
It’s very common to combine tab bar and navigation controllers, as illustrated in Figure 4. To do this, you simply add navigation controllers to a tab bar controller (however, you should never add a tab bar controller to a navigation controller).
So it's likely to be against the Human Interface guidelines and so could you get rejected.
I'm trying to do this very same thing. The application "Tweetie" is doing something similar. They have a TableView of accounts and then you select an account and TabBar appears.
Anyways, straight from Apple's Documentation:
pushViewController:animated:
Pushes a view controller onto the receiver’s stack and updates the display.
(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
Parameters
viewController
The view controller that is pushed onto the stack. It cannot be an instance of tab bar controller. This method does nothing if the view controller is already on the stack.
animated
Set this value to YES to animate the transition. Pass NO if you are setting up a navigation controller before its view is displayed.
So maybe we're just stuck using a TabBar and not a TabBarController?
-JP