0

I have a storyboard in which I have specified a parent view controller and two container views (made up of two UITableViewControllers). In my parent view controller I have buttons that are used to filter the content of the two tables.

My problem is figuring out how to send messages to the container views to perform these filters. I imagine we use delegates but is there a best practice way of implementing these delegates?

Carl Veazey
  • 18,392
  • 8
  • 66
  • 81
chongzixin
  • 1,951
  • 4
  • 28
  • 55
  • Do you have references to the contained view controllers in the parent? – Carl Veazey Sep 28 '13 at 04:00
  • I am still in the midst of implementing this so I can hold references to the contained view controllers if required. Will that be the right way to do this? – chongzixin Sep 28 '13 at 04:14

2 Answers2

1

Subject to some caveats, you could define properties for each of the two contained tables, connect the outlets in your .xib, and message them directly in your button handlers.

For example:

@interface ParentViewController : UIViewController

@property (nonatomic) IBOutlet Table1Class *table1;
@property (nonatomic) IBOutlet Table2Class *table2;

@end

@implementation ParentViewController

...

- (IBAction)table1FilterButton:(UIButton *)sender
{
    [self.table1 filterBy:...];
}

- (IBAction)table2FilterButton:(UIButton *)sender
{
    [self.table2 filterBySomethingElse:...];
}

@end

Now, the caveats - you probably won't want to do this if you anticipate that the number of contained view controllers is likely to grow significantly, as it will be unwieldy to have table1, table2, table3, ..., tableN. You'll probably also want to find a way to extract a common interface (in the form of a protocol) from the two contained view controllers, in order to write less divergent code for handling the filtering of each table.

Maybe something like this, instead:

@protocol ContainedTableProtocol

@property (nonatomic) NSPredicate *contentFilterPredicate;
@property (nonatomic) NSComparator sortComparator;

@end

@interface ParentViewController : UIViewController

@property (nonatomic) IBOutlet UITableViewController<ContainedTableProtocol> *table1;
@property (nonatomic) IBOutlet UITableViewController<ContainedTableProtocol> *table2;

@end


@implementation ParentViewController

- (IBAction)filterTable1ButtonAction:(UIButton *)sender
{
    [self filterTable:self.table1];
}

- (IBAction)filterTable2ButtonAction:(UIButton *)sender
{
    [self filterTable:self.table2];
}

- (void)filterTable:(UITableViewController<ContainedTableProtocol> *)table
{
    // Create predicate and comparator as needed...
    NSPredicate *predicate = ... ;
    NSComparator comparator = ... ;

    table.contentFilterPredicate = predicate;
    table.sortComparator = comparator;
}

@end

This uses a common interface to apply the filtering operations to each table view controller, and then codes to that interface rather than an API specific to a particular Table1Class or Table2Class.

Carl Veazey
  • 18,392
  • 8
  • 66
  • 81
  • Sorry I am getting back to this a little late. While attempting your suggestion, I got stuck at trying to assign outlets in my `.xlb`. To clarify further I created outlets for my `ViewControllers` instead of the tables because the ViewControllers are in-charge of downloading data for the tables. Can I not assign outlets to ViewControllers? – chongzixin Nov 03 '13 at 15:36
  • @user1258600 You can, as long as the types match. It sounds like maybe you're trying to connect a `UIViewController` outlet to a `UITableView` object in the nib; that won't work as they are incompatible types. For other view controllers, I find it's usually best to make them all top level objects in the nib, and their `view` outlets connected to appropriate views. – Carl Veazey Nov 03 '13 at 23:20
  • @CarlVeazey what about adding tags to tables and using a switch statement to tell which table sent the message to the method? – Juan Boero Nov 12 '15 at 14:20
0

You can see the answer at How do I create delegates in Objective-C?.

The simpler way is declare the delegate in the Childs and implement in the parent (ie: The childs send data to the parent).

Community
  • 1
  • 1
mamcx
  • 15,916
  • 26
  • 101
  • 189
  • Thanks for the response! Can I clarify how the "child send data to the parent" part works in the case of filtering? I am thinking when I click any of the filter buttons I will send data to the child asking them to sort themselves. I cant figure out how the upward sending from child to parent work in this case though – chongzixin Sep 28 '13 at 04:00
  • A delegate function is like any function. Send anything you want. You can send the predicate, or the ID of the object, or any object or block. How do you will do it if is a normal function? Then do the same. – mamcx Sep 29 '13 at 22:23
  • Sorry I am getting back to this a little late, I got down to tackling this problem using delegates like you recommended. But now I find myself having to have two way communications between the parent and children view controllers. This link (http://stackoverflow.com/questions/2168893/can-two-view-controllers-be-delegates-for-one-another) seems to indicate that this is bad design. Am I thinking about something wrongly? – chongzixin Nov 03 '13 at 15:32