开发者

Simple way to separate UITableview datasource and delegate from main UIViewController class?

开发者 https://www.devze.com 2022-12-17 17:25 出处:网络
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.

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


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.


You can create separe classes (with UITableViewDelegate , UITableViewDataSource) and add them in IB as external files and link the IBActions


In IB, you can drag a 'External Object' from Library->Cocoa Touch->Controllers into your xib window. You can then select that object, view the inspector, and set the class. It is now available to serve as a delegate, etc.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号