conorgriffin
conorgriffin

Reputation: 4339

How do I make a UIViewController the delegate for a separate UITableViewController?

I have a UITabBarController which has on one of its tabs, a UINavigationController. The UINavigationController then has a custom UIViewController as its main view.

Based on an IBAction triggered by a button in the custom UIViewController I'm pushing a UITableView controller onto the UINavigationController stack like so. (Note: these are only snippets of the actual code).

Header file for main UIViewController:

@interface ATMs : UIViewController <CLLocationManagerDelegate, NSFetchedResultsControllerDelegate, MKMapViewDelegate> {
}
- (IBAction) showLocationList;
@end  

Implementation file for main UIViewController:

@implementation ATMs
- (void)showLocationList {

    LocationList *locationTableController = [[LocationList alloc] initWithNibName:@"LocationList" bundle:nil];

    [self.navigationController pushViewController:locationTableController animated:YES];
    [locationTableController release];

}

The locationTableController view controller does a fetch to Core Data for a list of objects and displays them on the table. When a user selects a row, I want the following things to happen:

I tried to do this by using the [locationTableController setDelegate:self]; in showLocationList just beneath where I alloc the UITableViewController and adding the UITableViewDelegate to the header for ATMs.
But when I do the above, I get a build error saying that locationTableController may not respond to setDelegate.

Upvotes: 1

Views: 4462

Answers (2)

Rog
Rog

Reputation: 18670

In simple terms and without examining the rest of your code, you need to instantiate the UITableViewController and set its tableView (not the TableViewController) delegate as self.

Then you can implement - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath in your ATM UIViewController and it will be called once a row is selected in your tableView.

I'd also present your tableViewController modally as per code below, and declare it as an instance variable so you can dismiss it when the tableview delegate method is called:

@class LocationList
@interface ATMs : UIViewController
{
   LocationList *locationTableController
   ...
}

And in your implementation:

@implementation ATMs
...
- (void)showLocationList 
{
    locationTableController = [[LocationList alloc] initWithNibName:@"LocationList" bundle:nil];
    locationTableController.tableView.delegate = self;
    [self presentModalViewController:locationTableContrller animated:YES];
    [locationTableController release];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [locationTableController dismissModalViewControllerAnimated:YES];
    // Rest of your implementation code here
}

Upvotes: 2

iHS
iHS

Reputation: 5432

This can be achieved by various approaches like : -

  1. Delegation pattern
  2. Notifications
  3. By using class methods (getter/setters), in ATM controller, on in some other manager class
  4. Key Value Observations.

but I think the best approach would be to create your own delegate method, and send the callback when row gets selected in LocationList, along with the data you want on ATM controller

Upvotes: 0

Related Questions