I’m learning Xcode 4.2 with Storyboards and trying to make a universal app.
All works well on the iPhone but the iPad side has an issue with assigning 3 text fields (1 TextField, 2 TextViews) to the detail view of a split view controller.
I used the new ability in Storyboard where I link up the new fields in the detail view to the detail header file and it automatically creates the property and synthesize statements (very nice feature).
But when I get to the point where I wish to assign values to the detail fields (method drinkChanged), nothing gets displayed in the DetailViewController view. I validated that the dictionary values are there at the time of assignment.
What’s interesting is that when the method refreshView is called when the viewWillAppear gets invoked, then it works. But if the method refreshView is called by drinkChanged (meaning the user has selected a row on the MasterViewController table), then it does not work.
Anyone know where I might be missing the bus?
Here’s my code:
MasterViewController.h
#import <UIKit/UIKit.h>
@interface MasterViewController : UITableViewController {
NSMutableArray *drinks;
}
@property (nonatomic, retain) NSMutableArray *drinks;
@end
MasterViewController.m
#import "MasterViewController.h"
#import "DetailViewController.h"
#import "AddDrinkViewController.h"
#import "DrinkConstants.h"
@implementation MasterViewController
@synthesize drinks;
.
.
.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (!self.editing) {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
NSLog(@"didSelectRowAtIndexPath...iPad");
// Pass the selected object to the drinkChanged method in DetailViewController.m.
DetailViewController *splitViewDetailView = [self.storyboard instantiateViewControllerWithIdentifier:@"Detail"];
[splitViewDetailView drinkChanged:[self.drinks objectAtIndex:indexPath.row]];
}
else {
NSLog(@"didSelectRowAtIndexPath...iPhone");
DetailViewController *detailViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"Detail"];
detailViewController.drink = [self.drinks objectAtIndex:indexPath.row];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
}
}
else {
AddDrinkViewController *editingDrinkVC = [self.storyboard instantiateViewControllerWithIdentifier:@"AddDrink"];
editingDrinkVC.drink = [self.drinks objectAtIndex:indexPath.row];
editingDrinkVC.drinkArray = self.drinks;
[self.navigationController presentModalViewController:editingDrinkVC animated:YES];
}
}
DetailViewController.h
#import <UIKit/UIKit.h>
@interface DetailViewController : UIViewController {
NSDictionary *drink;
}
@property (strong, nonatomic) id detailItem;
@property (nonatomic, retain) NSDictionary *drink;
@property (strong, nonatomic) IBOutlet UITextField *nameTextField;
@property (strong, nonatomic) IBOutlet UITextView *ingredientsTextView;
@property (strong, nonatomic) IBOutlet UITextView *directionsTextView;
- (void) refreshView;
- (void) drinkChanged:(NSDictionary *) newDrink;
@end
DetailViewController.m
#import "DetailViewController.h"
#import "DrinkConstants.h"
@interface DetailViewController ()
- (void)configureView;
@end
@implementation DetailViewController
@synthesize detailItem;
@synthesize drink;
@synthesize nameTextField;
@synthesize ingredientsTextView;
@synthesize directionsTextView;
.
.
.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"viewWillAppear");
[self refreshView];
}
- (void) refreshView {
NSLog(@"refreshView");
// Set up our UI with the provided drink.
self.nameTextField.text = [self.drink objectForKey:NAME_KEY];
self.ingredientsTextView.text = [self.drink objectForKey:INGREDIENTS_KEY];
self.directionsTextView.text = [self.drink objectForKey:DIRECTIONS_KEY];
NSLog(@"NAME_KEY = %@", [self.drink objectForKey:NAME_KEY]);
NSLog(@"INGREDIENTS_KEY = %@", [self.drink objectForKey:INGREDIENTS_KEY]);
NSLog(@"DIRECTIONS_KEY = %@", [self.drink objectForKey:DIRECTIONS_KEY]);
NSLog(@"nameTextField = %@", self.nameTextField.text);
NSLog(@"ingredientsTextView = %@", self.ingredientsTextView.text);
NSLog(@"directionsTextView = %@", self.directionsTextView.text);
}
- (void) drinkChanged:(NSDictionary *) newDrink {
NSLog(@"drinkChanged");
self.drink = newDrink;
[self refreshView];
}
NSLog Output
GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Mon Aug 8 20:32:45 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin".sharedlibrary apply-load-rules all
Attaching to process 1187.
2012-01-31 13:10:26.061 DrinkMixer[1187:f803] viewDidLoad
2012-01-31 13:10:26.087 DrinkMixer[1187:f803] viewWillAppear
2012-01-31 13:10:26.088 DrinkMixer[1187:f803] refreshView
2012-01-31 13:10:26.089 DrinkMixer[1187:f803] NAME_KEY = (null)
2012-01-31 13:10:26.090 DrinkMixer[1187:f803] INGREDIENTS_KEY = (null)
2012-01-31 13:10:26.090 DrinkMixer[1187:f803] DIRECTIONS_KEY = (null)
2012-01-31 13:10:26.091 DrinkMixer[1187:f803] nameTextField = (null)
2012-01-31 13:10:26.091 DrinkMixer[1187:f803] ingredientsTextView =
2012-01-31 13:10:26.092 DrinkMixer[1187:f803] directionsTextView =
2012-01-31 13:10:32.878 DrinkMixer[1187:f803] didSelectRowAtIndexPath...iPad
2012-01-31 13:10:32.879 DrinkMixer[1187:f803] drinkChanged
2012-01-31 13:10:32.879 DrinkMixer[1187:f803] refreshView
2012-01-31 13:10:32.880 DrinkMixer[1187:f803] NAME_KEY = Blue Dog
2012-01-31 13:10:32.880 DrinkMixer[1187:f803] INGREDIENTS_KEY = vodka,grapefruit juice
2012-01-31 13:10:32.881 DrinkMixer[1187:f803] DIRECTIONS_KEY = Combine both while cold.
2012-01-31 13:10:32.881 DrinkMixer[1187:f803] nameTextField = (null)
2012-01-31 13:10:32.882 DrinkMixer[1187:f803] ingredientsTextView = (null)
2012-01-31 13:10:32.882 DrinkMixer[1187:f803] directionsTextView = (null)
The last 3 lines in the NSLog are where I’m expecting to get the values from the dictionary keys but instead they come back (null).
I needed an example of a Split View Controller that used the Storyboard (not xibs). After searching the web some more I found an answer.
See link below.
iOS 5 Simple Master-Detail View Application With Storyboard Template Example