0

Ok so I am trying to pass a string from one view controller to another via the AppDelegate. I want to stay on the current view while this happens.

This is the main body of the code I am currently using to do this:

AppDelegate *dataCenter = (AppDelegate *)[[UIApplication sharedApplication] delegate];
MyMealViewController *vc = [[MyMealViewController alloc] initWithNibName:nil bundle:nil];

dataCenter.selectedMenuItem = recipeLabel.text;

[self presentViewController:vc animated:YES completion:NULL];

When I run the program I am able to confirm that the string is correctly passed. However, then the view on the simulator just turns black. I assume that this is because initWithNibName is set to nil.

So my question is: how should I change my code so that the string will still be passed, but the current view will continue to be displayed on the iphone. Is there a line of code that I could write that would just reload the current view?

Thanks for your help with this issue. I am new to xcode so I may be making a very basic error. Please let me know if any additional information would be helpful in answering this question.

1 Answers1

1

Edit: It looks like you want to show a list of food items in the first view. Tapping an items opens a detail view. From that detail view, the user can press a button to add it to the meal. Eventually, they can tap a button on the first view to open the meal view, which should contain all of the items that they selected.

If this is the case, keep an array on the first view controller, and make sure the detail (second) view controller has a reference to the first view controller when it is presented. This will let us use that array. Note that there are better ways to architect this, but this will work for now:

@interface FoodListViewController : UIViewController
@property (strong, nonatomic) NSMutableArray *foodItems
@end

@implementation FoodListViewController
- (void)showFoodItem
{
    FoodItemDetailViewController *detailViewController = [[FoodItemDetailViewController alloc] initWithNibName:nil bundle:nil];
    detailViewController.foodListController = self;
    [self presentModalViewController:detailViewController animated:YES];
}
@end

Once the detail view is presented, tapping the 'add to meal' button should add the current 'mealItem' to the array. In your example, you were using strings - if you would rather keep an array of strings for some reason, I'll leave that to you.

@interface FoodItemDetailViewController : UIViewController
@property (nonatomic, weak) FoodItemsViewController *foodListController;
@end

@implementation FoodItemDetailViewController

- (IBAction)buttonTapped:(id)sender
{
    [self.foodListController.foodItems addObject:self.mealItem];
    // Update the UI to let the user know that the item was added to the meal
}

@end

Finally, when it comes time to present the MealDetailsViewController, just pass it the array that you have been building:

@interface MealDetailsViewController : UIViewController
@property (nonatomic, strong) NSArray *foodItems;
@end

@implementation MealDetailsViewController
    // Set foodItems before this view controller is presented, then use it to drive the
    // UITableView data source, or find some other way of displaying it.
@end

As you can see, both the second and third view controllers are presented by the first. View controllers (nearly) always form a hierarchy - so keeping your data at the top of that hierarchy (by storing it in FoodListViewController) lets you neatly pass it down the hierarchy as you present other view controllers.

Tim
  • 226
  • 1
  • 2
  • 1
    My apologies if this is extremely obvious, but which part of my above code would I delete so that I would not create the MyMealViewController? It seems that if I delete any of the lines of code then the string no longer gets passed. – Andrew Schutts Dec 06 '12 at 21:45
  • Just leave the two lines where you get the reference to your app delegate (dataCenter), and set selectedMenuItem. The string will now be stored in the app delegate. – Tim Dec 06 '12 at 22:20
  • When should MyMealViewController be displayed? – Tim Dec 06 '12 at 22:20
  • So I'm taking your advice to mean to just leave: "AppDelegate *dataCenter = (AppDelegate *)[[UIApplication sharedApplication] delegate];" and "dataCenter.selectedMenuItem = recipeLabel.text;" That's what I thought to do too but when I delete any of the other lines the string is no longer passed to the other view controller. – Andrew Schutts Dec 06 '12 at 22:36
  • Let me explain the basic structure/function of my app and maybe that will help: The user is presented with a table of items in the first view. They can select an item to get a second detail view. In that second detail view they can press a button to send the name of that item to a table in a third view (the MyMealViewController view). Then, when they are done selecting items to send to the table in the third view, they can navigate to the third view by way of a button on the first view. The MyMealViewController will be displayed at that time. – Andrew Schutts Dec 06 '12 at 22:41
  • I think I may just need a way to reload the current screen, is their a built-in function or method that I can use to do this? – Andrew Schutts Dec 06 '12 at 22:46
  • I made a monster edit to the original answer based on where I believe your project is going. I don't believe reloading the screen will do anything for you - this really comes down to how your data is structured and how it is handed off between parts of your app. See if the updated answer gets you any closer. – Tim Dec 06 '12 at 23:12
  • Thank you so much for your extensive answer! I think I am very close to getting everything to work. I am still getting one error though: When I inserted the line "@property (nonatomic, weak) FoodItemsViewController *foodListController;" from the second block of your answer, I changed "FoodItemsViewController" to "ViewController" because that is the name of my first and main viewcontroller. Now, however, I get an error that says "Unknown Type Name: ViewController" – Andrew Schutts Dec 07 '12 at 20:45
  • It seems like xcode doesn't recognize the name of my first view controller when I try to access it in my second view controller. Or else the fact that it is named "ViewController" causes it to confuse the name with "UIViewController". – Andrew Schutts Dec 07 '12 at 20:46
  • Any thoughts would be appreciated but please do not feel obligated at all since you have already helped me so much. I'll be working on figuring this out regardless. Thanks again! – Andrew Schutts Dec 07 '12 at 20:47
  • Hmm so I added "@class ViewController;" to my "FoodItemDetailViewController.h" file and that seems to have fixed the problem I just mentioned. So now everything builds correctly. Except "[self.foodListController.foodItems addObject:self.recipeName];" doesn't actually load anything into the "self.foodLisController.foodItems" array. More stuff for me to figure out I suppose! – Andrew Schutts Dec 07 '12 at 21:09
  • Excellent. Make sure that the foodItems array actually exists and is not nil, by putting something like this in the initWithNibName:bundle: method: "_foodItems = [[NSMutableArray alloc] init];" – Tim Dec 07 '12 at 21:12
  • Is the "[self presentModalViewController:detailViewController animated:YES];" line of code necessary? When I include it the app starts to transition between views but then the screen on the simulator just turns to black. – Andrew Schutts Dec 07 '12 at 21:29