Table View View Controller Show Next View - ios

Im working with table view controllers within story board.
I currently have one tableview controller embedded in navigation controller in my storyboard. This table view controller is linked to an ObjectiveC file.
Through code i can display another table view controller with the correct data using the tableView didSelectRowAtIndexPath method.
code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
WorkoutType *workoutType = (WorkoutType *)[self.fetchedResultsController objectAtIndexPath:indexPath];
WorkoutSetViewController *detailViewController = [[WorkoutSetViewController alloc] initWithWorkoutType:workoutType];
[self.navigationController pushViewController:detailViewController animated:YES];
}
But if i try to add another table view controller in storyboard, associate it with an objectiveC view controller file and connect the first TVC to it, That table view controller is not shown upon running the code.
I need to customise the second table view visually and have tried to use a segue push...as follows:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"show"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
WorkoutType *workoutType = (WorkoutType *)[self.fetchedResultsController objectAtIndexPath:indexPath];
//WorkoutSetViewController *detailViewController = [[WorkoutSetViewController alloc] initWithWorkoutType:workoutType];
WorkoutSetViewController *destViewController = segue.destinationViewController;
destViewController.workoutType = workoutType;
//[self.navigationController pushViewController:detailViewController animated:YES];
}
}
But when i run this code, the second table view controller doesn't even load although the application doesn't crash.
Whatever I am doing wrong must be simple, any help would be appreciated.
Thank You

Simple You have to navigate through below code. (No need to set storyboard when you working in same storyboard ViewController)
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexpath.row==0)//for first row click
{
WorkoutSetViewController *objWorkoutSetVC=[[WorkoutSetViewController alloc] i nitWithNibName:#"WorkoutSetViewController" bundle:nil];
[self.navigationController pushViewController:objWorkoutSetVC animated:YES];
}
else if(indexpath.row==1)//for second row click
{
//Put code in which screen you have to navigate
}
}

Do NOT Alloc init your new view controller. Use this code instead:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
WorkoutSetViewController *detailViewController = (WorkoutSetViewController *)[storyboard instantiateViewControllerWithIdentifier:#"coolID"];
[self.navigationController pushViewController:detailViewController animated:YES];
For MainStoryboard write your storyboard name and for coolID write your view controller id name which you set in your storyboard.

Related

Failed to push to a View Controller in iOS

I'm a very beginner to iOS development. I made a navigation application in iOS to view some details in another view when table view cell tap. I did the following code,
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
LawyerViewController *dvc = [self.storyboard instantiateViewControllerWithIdentifier:#"LawyerViewController"];
NSLog(#"%#",[self.myObject objectAtIndex:indexPath.row]);
dvc.lawyer = [self.myObject objectAtIndex:indexPath.row];
[self.navigationController pushViewController:dvc animated:YES];
}
This is going to the next view. But dvc.lawyer is not null here. It's null on Next View page.
Reading the Value in Next page
NSLog(#"%#",self.lawyer.firstName);
How can I fix this.
Thanks in Advance!
You are supposed to instantiate ViewControllers in another way, if you use storyboard segues. You need to implement prepareForSegue where you can Access the segues destinationViewController like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// reference to the destination view controller
LawyerViewController *vc = [segue destinationViewController];
// Pass any data
vc.lawyer = self.myObject[[self.tableView indexPathForSelectedRow].row]; // Not tested
}
}

DidSelectRowAtIndexPath using a story Board

In my app I am using the following didSelectRowAtIndexPath method to go to a viewController, but I am working within an story Board, and an exception is thrown telling me that the nib file is not found. How should I change the method to open the new viewController without exceptions?:
//link to the next view
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
EmpresasTableViewController *detailViewController = [[EmpresasTableViewController alloc] initWithNibName:#"EmpresasTableViewController" bundle:nil];
detailViewController.title =[[categorias objectAtIndex:indexPath.row]objectForKey:#"idCategoria"];
detailViewController.categoriaDescription = [categorias objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailViewController animated:YES];
}
you have to make an identifier (detailViewController for example)for you ViewController in your storyboard and then instantiate like this your EmpresasTableViewController
EmpresasTableViewController *detailViewController =[self.storyboard instantiateViewControllerWithIdentifier:#"detailViewController"];
i hope that help you

didSelectRowAtIndexPath or prepareForSegue to use?

i want to be able to select a item in my tableview and get to the correct view.
say i have two items in my uitableview. one has a value of ubuntu other has a value of arch- in my plist from arraA i have a SystemID which holds the text Ubuntu/Arch, never both
now when i select the one with ubuntu i want it to push to a new view where ubuntu stuff is
and if i go back and select arch it will again push me to a view where arch stuff is
so far i made this and it's not working as intended:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *segueName = nil;
if ([[arrayA valueForKey:#"SystemID"]isEqualToString:#"Ubuntu Linux"]) {
ActionViewController *controller = [[ActionViewController alloc] initWithNibName:#"Ubuntu Linux" bundle:nil];
controller.Serverinfo = [arrayA objectAtIndex:indexPath.row];
[self.navigationController pushViewController:controller animated:YES];
}
else if ([[arrayA valueForKey:#"SystemID"]isEqualToString:#"Arch Linux"]) {
ActionViewController *controller = [[ActionViewController alloc] initWithNibName:#"Arch Linux" bundle:nil];
controller.Serverinfo = [arrayA objectAtIndex:indexPath.row];
[self.navigationController pushViewController:controller animated:YES];
}
[self performSegueWithIdentifier: segueName sender: self];
}
also tried prepare forsegue
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([arrayA valueForKey:#"Arch Linux"])
{
ActionViewController *controller = (ActionViewController *)segue.destinationViewController;
NSIndexPath *indexPath = [self.mainTableView indexPathForSelectedRow];
controller.Serverinfo = [arrayA objectAtIndex:indexPath.row];
NSLog(#"hostname = %#", controller.Serverinfo);
}
if ([arrayA valueForKey:#"Ubuntu Linux"]) {
ActionViewController *controller = (ActionViewController *)segue.destinationViewController;
NSIndexPath *indexPath = [self.mainTableView indexPathForSelectedRow];
controller.Serverinfo = [arrayA objectAtIndex:indexPath.row];
NSLog(#"hostname = %#", controller.Serverinfo);
}
}
arrayA is a NSMutableArray that read from a plist that you can see here
Replace your method to:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([arrayA[indexPath.row][#"SystemID"]isEqualToString:#"Ubuntu Linux"]) {
//ActionViewController *controller = [[ActionViewController alloc] initWithNibName:#"Ubuntu Linux" bundle:nil];
// Make sure you replace Storyboard with your storyboard name
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
ActionViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"Ubuntu Linux"];
controller.Serverinfo = [arrayA objectAtIndex:indexPath.row];
[self.navigationController pushViewController:controller animated:YES];
}
else if ([arrayA[indexPath.row][#"SystemID"]isEqualToString:#"Arch Linux"]) {
ActionViewController *controller = [[ActionViewController alloc] initWithNibName:#"Arch Linux" bundle:nil];
controller.Serverinfo = [arrayA objectAtIndex:indexPath.row];
[self.navigationController pushViewController:controller animated:YES];
}
}
You don't need to call [self performSegueWithIdentifier: segueName sender: self]; in didSelectRow because you already push your view in didSelectRow method. If you call it you puts the view twice.
Ooh boy, you're off in the weeds.
First, stop talking about pushing a "view." The term view and view controller are NOT interchangeable. A view is an object that appears on the screen. A view CONTROLLER is an object that manages a collection of views (usually the entire screen.)
You push a view controller, not a view. The view controller then displays it's content view on the screen.
Now, as to your code.
The if statement in your tableView:didSelectRowAtIndexPath: method is messed up.
if ([[arrayA valueForKey:#"SystemID"]isEqualToString:#"Ubuntu Linux"])
You don't want to use valueForeKey on an array. That method attempts to call valueForKey on every object in your array, and what it returns is an array of the results.
Arrays are indexed by a numeric index, not a key. You want an array as the data source for a table view.
What you want to do is to fetch the object at your selected row from your array.
In order to help you further, though, you need to explain what you have stored in your arrayA. Is it an array of dictionaries? An array of strings?
Also, you are mixing NIB based view controller code with storyboard code. You can certainly use both in the same program if you need to, but as a beginner you probably should not.
In your tableView:didSelectRowAtIndexPath method you're creating a view controller with initWithNibName, pushing it, and then calling performSegueWithIdentifier. You want to do one or the other, not both.
Use storyboard with prepareForSegue

Segue not passing data to destination

I have two table view controllers, one containing all the US states, the other presenting a list of data for the selected state. I have set up a segue in my main storyboard from the view controller (not the cell), and given it an identifier. For reasons beyond the scope of this post, I need to programmatically perform the segue without using the prepareForSegue method.
The source table view controller (AllStatesTableViewController) needs to execute the segue in the didSelectRowAtIndexPath method of the tableview.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
stateID = [statesDict objectForKey:cell.textLabel.text];
DetailTableViewController *destination = [[DetailTableViewController alloc] init];
stateGauges = [[GaugeList alloc] initWithStateIdentifier:stateID andType:nil];
// at this point stateGauges is NOT nil
[destination setStateGauges:stateGauges];
[self performSegueWithIdentifier:#"sgShowStateDetail" sender:self];
}
The segue performs as intended in that it navigates to its destination, but stateGauges is nil in the destination table view controller. It is not nil in the source table view controller. stateGuages is declared as a property in DetailTableViewController. Obviously I am doing something wrong. Any suggestions?
Thanks! V
On your storyboard you need to choose to push your segue from your cell.
and use your prepareForSegue to pass data :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showDetail"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DetailTableViewController *detailTableViewController = segue.destinationViewController;
// Pass data here
destViewController.stateGauges = stateGauges;
}
}
Have a look here for more information
I ran into this before too. I found that when I let the storyboard handle the segue, it instantiates a new view controller. This is why stateGauges is nil, because you set stateGauges in your programmatically created view controller, not the one the storyboard created. If you won't use prepareForSeque, remove the segue from your AllStatesViewController to your DetailTableViewController in your storyboard. Then programmatically instantiate the storyboard, the view controller, setGauges, then present your view controller. Also, make sure you put "ShowStateDetail" in the "Storyboard ID" field, in the Identity section, on that DetailTableViewController in your storyboard.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
stateID = [statesDict objectForKey:cell.textLabel.text];
DetailTableViewController *destination = [[UIStoryboard storyboardWithName:#"yourStoryBoardName" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"ShowStateDetail"];
stateGauges = [[GaugeList alloc] initWithStateIdentifier:stateID andType:nil];
[destination setStateGauges:stateGauges];
[self presentViewController:destination animated:YES completion:nil];
}

Pushing a view in Storyboard

I am trying to use Table Views and navigation controllers. This is the code I would use if I was using NIB files. This piece of code would work fine if I was using NIB files, but I decided to try storyboard -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (_webViewController == nil) {
self.webViewController = [[[WebViewController alloc] initWithNibName:#"WebViewController" bundle:[NSBundle mainBundle]] autorelease];
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
_webViewController.entry = entry;
[self.navigationController pushViewController:_webViewController animated:YES];
}
I have created another scene in storyboard and have everything set up out there. When a user clicks a cell in this Table View they will be taken to that scene. This is what I wrote for the code but it is not right and I'm hopelessly stuck :( -
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"articleView"]){
UINavigationController *navigationController = segue.destinationViewController;
WebViewController *controller = (WebViewController *)navigationController.topViewController;
controller.webView = self;
}
Answer - Answers 2 and 3 are both right
I had a very similar problem 2 days ago, with the user selecting the disclosure accessory on a row and wanting to invoke a segue. What worked for me:
In storyboard, create segue "articleView" from the entire tableView controller (not the cell) to the next viewController.
Add the following method to your tableViewController:
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"articleView" sender:[self.tableView cellForRowAtIndexPath:indexPath]];
}
Just for you I also tested with tableView:didSelectRowAtIndexPath: and it works.
Enjoy,
Damien
If your table view is already embedded in a navigation controller (looks that way, from your first code snippet) then the destination view controller of your segue will be a WebViewController, not a navigation controller.
You can therefore have your prepareForSegue method pass the item directly across :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"articleView"])
{
WebViewController *controller = (WebViewController *)segue.destinationViewController;
RSSEntry *entry = [_allEntries objectAtIndex:[self.tableView indexPathForSelectedRow].row];
controller.entry = entry;
}
}
You may find this excellent two-part tutorial helpful
http://www.raywenderlich.com/5138/beginning-storyboards-in-ios-5-part-1

Resources