Shawn_Rong Shawn_Rong - 5 months ago 45
Objective-C Question

UITableView Delegate Method not getting called?

I' m trying to extract the UITableView Delegate method into a base class called

BaseTableProvider


//BaseTableProvider.h
@protocol RSTableProviderProtocol <NSObject>

- (void)cellDidPress:(NSIndexPath *) atIndexPath;

@optional
- (void)cellNeedsDelete:(NSIndexPath *) atIndexPath;

@end

@interface RSBaseTableProvider : NSObject <UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) NSMutableArray *dataSource;
@property (nonatomic, weak) id<RSTableProviderProtocol> delegate;

@end
//BaseTableProvider.m
@implementation RSBaseTableProvider
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [[UITableViewCell alloc]init];
return cell;
}
@end


And then I create a subclass of BaseTableProvider, and override two UITableViewDelegate Method in the subclass

//RSFeedListTableProvider.h
@interface RSFeedListTableProvider : RSBaseTableProvider

@end

//RSFeedListTableProvider.m
@implementation RSFeedListTableProvider

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [self.dataSource count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
RSFeedCell *cell = (RSFeedCell *)[tableView dequeueReusableCellWithIdentifier:kFeedCell];

if(cell == nil){
cell = [[RSFeedCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kFeedCell];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}

Feed *feed = (Feed *)self.dataSource[indexPath.row];

if (feed != nil) {
cell.titleText = feed.title;
cell.subTitleText = feed.summary;
}


return cell;
}

@end


I initialized the ListTablerProvider in a ViewController.

//RSFeedListViewController.m
@implementation RSFeedListViewController

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
_feedListView = [[RSFeedListView alloc] init];

self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

_provider = [[RSFeedListTableProvider alloc] init];
_provider.delegate = self;

return self;
}

#pragma mark -- Life Cycle

- (void)loadView{
RSFeedListView *aView = [[RSFeedListView alloc] initWithFrame:[UIScreen mainScreen].bounds];

self.feedListView = aView;
self.view = aView;

self.feedListView.tableView.delegate = _provider;
self.feedListView.tableView.dataSource = _provider;
}


But I can't see the cell built on the screen.I debuged the code found that UITableView Delegate Method in RSFeedListTableProvider was not called.Any one can help me?Thanks!

Answer

I think you did not implement the numberOfRowsInSection datasource method in your subclass RSFeedListTableProvider. So it will invoke the super class implementation

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

and there you are returning zero, so cellForRowAtIndexPath in your subclass never will be called.
Solution is implement numberOfRowsInSection in subclass and return proper count