5

I'm quite new to iOS development. I have read about the issues with ViewControllers becoming huge and would like to follow the design I have seen in the answer to this previous question UITableView issue when using separate delegate/dataSource for my app which has 2 different tables and couple of buttons on one screen. But somehow I get confused in the storyboard connections to make between TestTableViewController and TestTableTestViewController.

Can anyone provide a sample working project or some screen shots on how to connect the UITableView delegate, data source and connecting outlet to the separate custom UIViewController subclass (TestTableTestViewController) in storyboard please?

Also, does this design work with xCode 5 / iOS 7 and above?

Note: For those having moved to Swift I strongly recommend using swift extensions for the delegate & data source and in fact any other implementation of an inherited class or protocol as per the 'Grouping' section of Natasha The Robot's blog post here

Litome
  • 653
  • 8
  • 12
  • You can refer to following link:http://www.raywenderlich.com/50308/storyboards-tutorial-in-ios-7-part-1 – Saurav Nagpal Jun 26 '14 at 12:24
  • 1
    Thank you @SauravNagpal. Interesting tutorial but here again the TableView delegate/dataSource is handled by the same ViewController as it's container (PlayerViewController). What I am trying to achieve is a Home screen with "HomeScreenViewController.h/.m" that contains(and handles) several UI objects (2 buttons, 2 different custom tables both with custom cells) but where the delegate and dataSource for each table are handled/implemented in separate files. I'm starting to think that this is a design that is not possible in xCode5 anymore... Can anyone confirm/prove me wrong please? – Litome Jun 26 '14 at 15:18
  • According to me you cannot do that by using storyBoard. For that you need to implement through code. – Saurav Nagpal Jun 27 '14 at 07:38
  • Thanks for confirming @SauravNagpal! I'll do it programmatically then. – Litome Jun 27 '14 at 07:56

2 Answers2

2

Press and hold Ctrl and click + hold + drag on item you want to make outlet to .h file. it will make connection by itself you just have to name them. See This Video Tutorial

Also check these tutorials

Link 1

Link 2

iAhmed
  • 6,556
  • 2
  • 25
  • 31
  • 1
    Thank you but I'm not that new to iOS. I do know how to connect delegate, dataSource and IBOutlet for a simple table. In fact, I had a working table before I tried to extract the table management specific code to a separate set of files following the instructions in the previous question I've linked. But for some reason, xCode storyboard won't let me connect the delegate / dataSource or IBOutlet of the table view to the new view controller. I can click and drag as much as I want, it never sticks. – Litome Jun 26 '14 at 13:20
  • I've just checked all 3 linked tutorials you've kindly provided. It seems all 3 are for a basic table where the ViewController is also the TableView's delegate and dataSource. However, I'm trying to follow the design explained here: http://stackoverflow.com/questions/254354/uitableview-issue-when-using-separate-delegate-datasource and dissociate my table's delegate / dataSource from the main ViewController and can’t get the last 2 steps (storyboard connections) to connect. Any help on that please? – Litome Jun 26 '14 at 13:47
2

You have to create another class named as MyTableViewDataSource and implement TabbleViewDataSource methods in it. Create an a property of your data source class. Set data source in ViewController Here is the examle:

@interface MyTableViewDataSource ()
@property (nonatomic, assign) int sectionOneRows;
@property (weak) id<YourDelegate> delegate;
@property (nonatomic, strong) NSArray *dataSourceArray;
@end

@implementation MyTableViewDataSource
@synthesize delegate=_delegate;

-(id) initDataSourceWithdArray:(NSArray *)array
                                            delegate:(id)delegate
{
    if (self = [super init]) {
        self.dataSourceArray=array;
        self.delegate = delegate;
    }
    return self;
}

#pragma mark - UITableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return numberOfRows;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cellToReturn = nil;
    //Your code here
    return cellToReturn
}

#pragma mark - UITableView Delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    //Your logic here
    //implement the delegate method in you ViewController
        [self.delegate performSelector:@selector(loadDetailsAtIndexPath:)withObject:indexPath];
    }
}

In your ViewController:

self.myDataSource = [[MyTableViewDataSource alloc] initDataSourceWithdArray:self.dataArray delegate:self];
[self.myTableView setDataSource:self.myDataSource];
[self.myTableView setDelegate:self.myDataSource];
[self.myTableView reloadData];

Your delegate method:

-(void)loadDetailsAtIndexPath:(NSIndexPath *)indexPath
{
    MyDetailViewController *myDetailController = [[MyDetailViewController alloc] initWithNibName:@"MyDetailViewController" bundle:nil];
    //Your logic here
    [self.navigationController pushViewController:myDetailController animated:YES];
}

Go to the Connections Inspectors and make changes like this:

enter image description here

Data source for the tableView will be set programatically here rather in IB. I hope this will help you.

iBug
  • 2,334
  • 3
  • 32
  • 65
  • 1
    Thanks, that might be a programatic way of doing it. I'll try. However, the previous question I was referencing (and trying to follow) mentions doing the connection via the storyboard. That works fine for me when the main ViewController also acts as delegate and dataSource for the table but it seems impossible to connect the table's outlet/delegate/dataSource to the new UITableViewController (TestTableTestViewController in the referred post). Any help on the storyboard side of this please? – Litome Jun 26 '14 at 13:55
  • I suggest you to do this programmatically. Because you can handel your data source and flow with more control. – iBug Jun 27 '14 at 04:55
  • Thanks for your help @iBug. I'll do it programmatically and follow your example. – Litome Jun 27 '14 at 07:57
  • I've tried to work a bit more on this but without success so far. And I have couple more questions regarding your suggestion @iBug. I really do appreciate your help. Thank you! – Litome Jul 02 '14 at 09:32
  • In the sample code above, you seem to set the delegate twice: `self.myDataSource = [[MyTableViewDataSource alloc] initDataSourceWithdArray:self.dataArray delegate:self];` and `[self.myTableView setDelegate:self.myDataSource];` is that necessary or was it just to demonstrate 2 ways of doing it? – Litome Jul 02 '14 at 09:35
  • Also, I've followed your suggestion but I end up with a blanc table and the dataSource and delegate methods are never called. I think it's because the table's IBOutlet in the story board still points to the original ViewController not the new MyTableViewDataSource. Any idea on how to pass the IBOutlet reference along? – Litome Jul 02 '14 at 09:36
  • See the edit. Yes it is essential. First delegate is towards your external datasource and second one is for your tableView and external datasource – iBug Jul 03 '14 at 04:23