I'm using Cocoanetic's pull-to-reload but with a twist: I would like the UITableView to be able to pull up, as it were, to load m开发者_运维问答ore data.
I customized the classes and have managed to adjust all functionality to support this. What got me stumped, basically, is where in my code to create and add the extra view.
I first tried to add it in viewDidLoad of Cocoanetic's class (a UITableViewController
):
- (void)viewDidLoad
{
[super viewDidLoad];
refreshHeaderView = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.view.bounds.size.height, 320.0f, self.view.bounds.size.height)];
refreshFooterView = [[EGORefreshTableFooterView alloc] initWithFrame:CGRectMake(0.0f, 0.0f + self.tableView.contentSize.height, 320.0f, 20.0f)];
[self.tableView addSubview:refreshHeaderView];
[self.tableView addSubview:refreshFooterView];
self.tableView.showsVerticalScrollIndicator = YES;
}
This does not work, as self.tableView.contentSize.height
is zero at this point, because the table hasn't loaded it's data yet.
Not to worry, I thought, and tried to add it in the viewDidLoad of the UITableViewController subclass I made:
- (void)viewDidLoad
{
[super viewDidLoad];
// stuff
self.model = [ListingModel listingModelWithURL:@"avalidurl" delegate:self];
refreshFooterView = [[EGORefreshTableFooterView alloc] initWithFrame:CGRectMake(0.0f, 0.0f + self.tableView.contentSize.height, 320.0f, 20.0f)];
[self.tableView addSubview:refreshFooterView];
}
Note I set the model first, but that also didn't work, for the same reason. I assume the table hasn't been layed-out yet. In frustration I gave my class a BOOL
property and an addFooter
method (the BOOL
to make sure it's only called once) called from tableView:cellForRowAtIndexPath:
which obviously is a far cry from The Right Way™
So what would, given this scenario, be The Right Way™?
The solution was easier than I thought and 7KV7 actually gave me the hint I needed.
- (void)viewDidLoad
{
[super viewDidLoad];
// stuff
self.model = [ListingModel listingModelWithURL:@"avalidurl" delegate:self];
/*
We're forcing a reload of the table here, that way the table has a
contentSize, so adding the footerView now works correctly.
*/
[self.tableView reloadData];
[self addRefreshFooter];
}
From this previous SO question Get notified when UITableView has finished asking for data? subclassing UITableView's reloadData is the best approach :
- (void)reloadData {
NSLog(@"BEGIN reloadData");
[super reloadData];
NSLog(@"END reloadData");
}
reloadData doesn't end before the table has finish reload its data. So, when the second NSLog is fired, the table view has actually finish asking for data.
If you've subclassed UITableView to send methods to the delegate before and after reloadData. It works like a charm.
精彩评论