ios Pass data between navigation controller - ios

I'm having a bit of a problem with my app, I have these view controllers below:
I have the locations view controller with an array of locations and I have a locations array in the Menu Table view controller, I need to pass the array from Locations to Menu Table, but I dont know how, can somebody Help me? I have tried this coding below:
-(void)pushMenuTableView
{
UIStoryboard *storyboard = self.storyboard;
UINavigationController *menuTableController = (UINavigationController *)[storyboard instantiateViewControllerWithIdentifier:#"MenuTableViewController"];
MenuTableViewController *menuController = (MenuTableViewController *) menuTableController.topViewController;
[self.navigationController pushViewController:menuTableController animated:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MenuTableViewController *mvc = [[MenuTableViewController alloc]init];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
Location *selectedLocation = [_locations objectAtIndex:[path row]];
[mvc setLocation:selectedLocation];
[self pushMenuTableView];
}

You are using two different MenuTableViewController objects. One you create using alloc/init and give the Location to and another that you obtain from the navigation controller and then push. You need to pass the data to the controller you're going to display instead of one you make temporarily.
How about using only one navigation controller and moving through the view controllers using segues?

You could try something like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIStoryboard *storyboard = self.storyboard;
MenuTableViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"MenuTableViewController"];
Location *selectedLocation = [_locations objectAtIndex:indexPath.row];
vc.location = selectedLocation;
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
[self presentViewController:nc animated:YES completion:nil];
}

Related

IOS navigate to new view but get a black screen

I have navigate to a new class with view by the below table view delegate method but I get a black screen returned.
#import "NewClass.h"
- (void)tableView: (UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName: #"MainStoryboard" bundle: [NSBundle mainBundle]];
NewClass *new = [storyboard instantiateViewControllerWithIdentifier: #"newDetail"];
new.array = localArray;
[self presentViewController: new animated: YES completion: nil];
}
I have NSLog the array on the new class there and the data is received in the new class, all the storyboard name, identifier tag are correct placed, but I don't know why I still getting a black screen, could anyone help me point out what is the error cause there?
try this code:
- (void)tableView: (UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath
{
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
NewClass * new = [storyboard instantiateViewControllerWithIdentifier:#"newDetail"];
new.array = localArray;
[self.navigationController pushViewController:new animated:YES];
}
It should be,
ViewController *new = [storyboard instantiateViewControllerWithIdentifier: #"newDetail"];
And make sure the id of your view controller is set to newDetail on storyboard

While pushing a viewcontroller there is a jerk in animation

For pushing a view controller I'm using following code. On tap of UITableViewCell need to push DetailViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row)
{
NSDate *object = self.objects[indexPath.row];
DetailViewController *controller = [DetailViewController new];
[self.navigationController pushViewController:controller animated:YES];
}
}
Now problem is I get a jerk while animating. Refer to screenshot
its because of transparency. just set a background color for your viewcontroller. thats all.
Most probably you're doing something "heavy" on the main thread, while loading DetailViewController.
Could you show us what are you doing in DetailViewController?
I think there is issue with allocating object and pushing same object.
Do the following changes, it will work fine.
Your code :
DetailViewController *controller = [DetailViewController new];
[self.navigationController pushViewController:controller animated:YES];
Replace :
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main"
bundle: nil];
MyViewController *controller = (MyViewController*)[mainStoryboard
instantiateViewControllerWithIdentifier: #"<your Storyboard ID>"];
it will work fine at my end.
Hope this help you.

self.navigationController is (null) in TableViewController which is on a TabBarController

I'm trying to create a small app in iOS. After the Login Page, I have a TabBarController and the first tab in it is a TableViewController. In didSelectRowAtIndexPath I'm trying to push one view controller for every selected row. The same view controller but self.navigationController is (null) when I print it using an NSLog and I'm not able to push the ViewController. HELP!!
Here's the sample Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here, for example:
// Create the next view controller.
PlayerDetailsViewController *detailViewController = [[PlayerDetailsViewController alloc] initWithNibName:#"PlayerDetailsViewController" bundle:nil];
detailViewController.myImg.image=[UIImage imageNamed:[self.arrNames objectAtIndex:indexPath.row]];
detailViewController.name.text=[self.names objectAtIndex:indexPath.row];
detailViewController.year.text=[self.draft objectAtIndex:indexPath.row];
detailViewController.height.text=[self.height objectAtIndex:indexPath.row];
detailViewController.weight.text=[self.weight objectAtIndex:indexPath.row];
detailViewController.pro.text=[self.pro objectAtIndex:indexPath.row];
detailViewController.ppg.text=[self.ppg objectAtIndex:indexPath.row];
detailViewController.apg.text=[self.apg objectAtIndex:indexPath.row];
detailViewController.rpg.text=[self.rpg objectAtIndex:indexPath.row];
NSLog(#"%#",self.navigationController);
[self.navigationController pushViewController:detailViewController animated:YES];
}
UPDATE: I got the navigationController to work but now, the data in the pushed view(PlayerDetails) in blank!!
It's just wrong that you haven't nested your firstViewController inside UINavigationController.
So I guess your code will be seems like this when creating UITabViewController.
[tabVC setViewControllers:[vc1,vc2,nil]];//tabVC = UITabViewController
And it need to be changed something like below;
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc1];
[tabVC setViewControllers:[nav,vc2,nil]];
Assume that the instance of UITabBarController is tabVC and the instance of UITableViewController is tableVC.
UINavigationController *nav = [[UINavigationController alloc initWithRootViewController:tabVC];
or
UINavigationController *nav = [[UINavigationController alloc initWithRootViewController:tableVC];
[tabVC setViewControllers:#[nav]];
Both will fix your problem.

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

Table View View Controller Show Next View

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.

Resources