The typical UITableView usage pattern is to have the main UIViewController become a target datasource and delegate for the UITableView it is holding on to.
Are there any simple and easy to follow tutorials that would help me figure out how to move the code that pertains to the UITableViewDelegate and UITableViewDataSource methods into a separate class and hook that to my UIViewController instead? I would ideally like to have both the delegate and datasource living in the same class.
Right now, I am creating the UITableView via Interface Builder and connecting its outlet to my controller class.
Typical code:
@interface MyController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
IBOutlet UITableview *myTableview;
}
I want to do something more like this:
@interface MyController : UIViewController
{
IBOutlet UITableview *myTableview;
}
@end
@interface MyTableSourceDelegate : NSObject<UITableViewDelegate, UITableViewDataSource>
{
}
@implementation MyTableSourceDelegate
// implement all of the UITableViewDelegate and methods in this class
@end
Datasource methods are used to generate tableView cells,header and footer before they are displaying.. Delegate methods provide information about these cells, header and footer along with other user action handlers like cell selection and edit..
A data source is almost identical to a delegate. The difference is in the relationship with the delegating object. Instead of being delegated control of the user interface, a data source is delegated control of data.
Methods for managing selections, configuring section headers and footers, deleting and reordering cells, and performing other actions in a table view.
I spend 2 hours to solve this problem:
It's working for me
// GenreDataSource.h
#import Foundation/Foundation.h
@interface GenreDataSource : NSObject <UITableViewDataSource> {
NSArray *dataSource;
CGSize cellSize;
}
@property(nonatomic, assign) CGSize cellSize;
@end
// GenreDataSource.m
#import "GenreDataSource.h"
@implementation GenreDataSource
@synthesize cellSize;
-(id)init{
self = [super init];
if ( self != nil ) {
dataSource = [[NSArray alloc] initWithObjects:@"All",@"Folk",@"Disco",@"Blues",@"Rock",@"Dance",@"Hip-Hop",@"R&B",@"Soul",@"Lounge",@"Techno",@"Bubstep", nil];
}
return self;
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [dataSource count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"CellPicker";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero] autorelease];
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
//сконфигурируем структуру
FontLabel *fLabel= [[FontLabel alloc] initWithFrame:CGRectMake(30,
5,
cellSize.width-30,
cellSize.height-5)
fontName:@"HelveticaNeueCondensedBlack"
pointSize:18.0f];
[fLabel setTextColor:[UIColor darkTextColor]];
[fLabel setTag:101];
[fLabel setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:fLabel];
[fLabel release];
}
FontLabel *fLabel = (FontLabel*)[cell viewWithTag:101];
[fLabel setText:[dataSource objectAtIndex:indexPath.row]];
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
@end
First thing is if you're using a UITableViewController subclass with interface builder you will want to disconnect the delegate and datasource outlets that are already hooked up by default. (Hint, look in the connections inspector). Check even if you have a tableView inside a viewController.
Second create your classes and make sure they conform to <UITableViewDelegate>
and <UITableViewDataSource>
. You're probably going to have to declare this contract in the .h file if you're using objc.
Third, In your view controller instantiate this class or two separate classes somewhere like viewDidLoad
, and then assign self.tableView.delegate = myCustomDelegateInstance
and self.tableView.dataSource = myCustomDataSourceInstance
.
Now, any calls that come through the controller will be dispatched to your custom handlers. Pretty basic.
The only reason to really do this is if you 1) have a very bloated controller, or 2) you need to reuse the dataSource and delegate methods somewhere else and you want to avoid code repetition. Otherwise, it's probably better practice to leave it put.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With