I have two class files. ViewController and ChooseServerView. A user clicks a cell within the ViewController class which pushes to the ChooseServerView. When a user makes a selection in ChooseServerView the value of that cell gets passed to the delegate. Now, these two views are in front of a navigation controller, so in the ChooseServerView there is a back button. When the user clicks back I want to update the cell in the first view with the new value from the delegate, make sense?
ViewController.h
#import <UIKit/UIKit.h>
#import "ChooseServerView.h"
@interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, serverUserChoice>
{
NSString *testLocation;
}
@property (nonatomic, retain) NSString *testLocation;
@end
View Controller.m
#import "ViewController.h"
#import "ChooseServerView.h"
#import "AppDelegate.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize testLocation;
- (void)viewDidLoad
{
NSUserDefaults *sharedPref = [NSUserDefaults standardUserDefaults];
testLocation =[sharedPref stringForKey:@"defaultLocation"];
NSLog(@"Location Chosen: %@",testLocation);
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
#pragma mark - Table View Methods
- (void) userDidChoose:(NSString *) server {
testLocation = server;
NSLog(@"Test Location %@", server);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; // Default is 1 if not implemented
{
return 2;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; // fixed font style. use custom view (UILabel) if you want something different
{
switch (section) {
case 0:
return @"Choose Test Location:";
break;
case 1:
return @"Choose Test Type:";
default:
return @"Unknown";
break;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
switch (section) {
case 0:
return 1;
break;
case 1:
return 1;
default:
return 0;
break;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *serverLocCell = [tableView dequeueReusableCellWithIdentifier:@"serverLocation"];
switch (indexPath.section) {
case 0:
serverLocCell.textLabel.text = testLocation;
serverLocCell.detailTextLabel.text = @"Change";
break;
case 1:
serverLocCell.textLabel.text = @"Speed Test";
serverLocCell.detailTextLabel.text = @"Change";
break;
default:
break;
}
return serverLocCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section) {
case 0:
[self performSegueWithIdentifier:@"toServerChoice" sender:self];
break;
case 1:
[self performSegueWithIdentifier:@"toTestType" sender:self];
break;
default:
break;
}
}
@end
ChooseServerView.h
#import <UIKit/UIKit.h>
@class ViewController;
@protocol serverUserChoice <NSObject>
@optional
- (void)userDidChoose:(NSString *) server;
@end
@interface ChooseServerView : UIViewController <UITableViewDataSource, UITableViewDelegate, serverUserChoice>
{
NSArray *serverSelection;
NSArray *tqServerSelection;
}
@property (nonatomic, retain) NSArray *serverSelection;
@property (nonatomic, retain) NSArray *qServerSelection;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property(retain) NSIndexPath* lastIndexPath;
@property (nonatomic, assign) id <serverUserChoice> serverDelegate;
@end
ChooseServerView.m
#import "ChooseServerView.h"
#import "ViewController.h"
#import "AppDelegate.h"
#define totalSections 2
#define standardSection 0
#define qualitySection 1
@interface ChooseServerView ()
@end
@implementation ChooseServerView;
@synthesize serverSelection;
@synthesize qServerSelection;
@synthesize lastIndexPath;
@synthesize serverDelegate;
- (void)viewDidLoad
{
serverSelection = [[NSArray alloc] initWithObjects:@"Chicgo, IL",@"London, UK",@"San Jose, CA",@"Washington, DC", nil];
qServerSelection = [[NSArray alloc] initWithObjects:@"Chicgo, IL (Q)",@"London, UK (Q)",@"San Jose, CA (Q)",@"Washington, DC (Q)", nil];
[super viewDidLoad];
}
#pragma mark - Table View Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; // Default is 1 if not implemented
{
return totalSections;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; // fixed font style. use custom view (UILabel) if you want something different
{
switch (section) {
case standardSection:
NSLog(@"Std Heading Set");
return @"Standard Test Locations:";
break;
case qualitySection:
NSLog(@"Qual Heading Set");
return @"Quality Test Locations:";
break;
default:
NSLog(@"Section Count Error");
return @"Section Count Error";
break;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
if (section == 0) {
NSLog(@"Std Loc Set");
return [serverSelection count];
}
else {
NSLog(@"Quality Loc Set");
return [qServerSelection count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *serverLoc = [tableView dequeueReusableCellWithIdentifier:@"serverSelection"];
switch (indexPath.section) {
case standardSection:
serverLoc.textLabel.text = [self.serverSelection objectAtIndex:indexPath.row];
break;
case qualitySection:
serverLoc.textLabel.text = [self.qServerSelection objectAtIndex:indexPath.row];
break;
default:
break;
}
return serverLoc;
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellvalue;
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
cellvalue = cell.textLabel.text;
[serverDelegate userDidChoose:cellvalue];
NSLog(@"Cell Selected is %@",cellvalue);
[cell setSelected:FALSE animated:TRUE];
}
@end
I can see the correct value gets passed to the delegate, I just don’t know how to “call” that delegate/method when going back using the automatic back button implemented by the nav controller.
Any ideas would be great.
As per answer below:
Added to my ViewController.h
@property (nonatomic, weak) IBOutlet UITableView *tableView;
Added to my ViewController.m
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView reloadData];
}

Still no joy at this stage. First cell fails to update upon pressing the back button as provided by the navigation controller.
Looks like you are almost there.
I think the issue is that your UITableView is not being reloaded to represent the updated value of testLocation. I don’t see a reference to the UITableView that is being managed by your ViewController, first add an outlet to ViewController.m to point to this table view.
Then, add the following in your ViewController.m
-(void) viewWillAppear:(BOOL)animated {
}
You also need to make sure you set your ViewController as the delegate of ChooseServerViewController. (You should rename ChooseServerView.m to ChooseServerViewController.m for clarity, as it’s a view controller subclass- I’ve referred to it as such below)
You can set the delegate by adding a prepare for segue method in ViewController.m – something like:
ChooseServerViewController *viewController = (ChooseServerViewController *)segue.destinationViewController;
viewController.serverDelegate = self;
}
I would also look into using UITableViewController for these two controller classes, since it appears that’s the type of functionality you are looking for.