I'm trying to load a single custom cell into a UITableView
and it keeps throwing an error
UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:
I have no idea why. I have linked my table view cell to the UITableViewCell definition in my code, but it keeps giving me this error. Here is my code; any help would be greatly appreciated.
#import "RegisterDeviceViewController.h"
@implementation RegisterDeviceViewController
@synthesize checkString;
@synthesize cellRegistration;
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
//Change UITableView Style to Grouped
- (id)initWithStyle:(UITableViewStyle)style {
// Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
style = UITableViewStyleGrouped;
if (self = [super initWithStyle:style]) {
}
return self;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
self.title = @"Registration";
[super viewDidLoad];
}
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 1) {
if (indexPath.row == 1) {
return cellRegistration;
}
}
return nil;
}
//Pass search type over to rootViewController section2
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
@end
Okay. That's not how UITableView works. When the table view needs to draw a cell (ie, a row); it invokes
tableView:cellForRowAtIndexPath:
on the object specified in thedataSource
property. It's your job to return a UITableViewCell from that method. This is how Apple does it (and how you should do it):The number of times that method will be invoked depends on the number of sections in the table view and the number of rows in each section. The process works like this:
numberOfSectionsInTableView:
on itsdataSource
(it knows it implements that method because thedataSource
must adhere to theUITableViewDataSource
protocol).numberOfSectionsInTableView:
returns a number greater than zero, the table view will invoke the delegate methodtableView:numberOfRowsInSection:
on thedataSource
. So ifnumberOfSectionsInTableView:
returns2
,tableView:numberOfRowsInSection:
will be invoked twice.tableView:numberOfRowsInSection:
returns a number greater than zero, the table view will invoke the delegate methodtableView:cellForRowAtIndexPath:
on thedataSource
' So iftableView:numberOfRowsInSection:
returns5
,tableView:numberOfRowsInSection:
will be invoked five times (once for each individual row).indexPath
variable):cell.textLabel.text = [someArrayYouHave objectAtIndex:indexPath.row];
.You are returning only one section, only one row
the section count and row count starts from 0.
Thats y you are getting this kinda error
Also refer this post for loading custom cells.
You wrote:
But your -tableView:cellForRowAtIndexPath: says, in part:
After reading the error message and looking at the code, do you not see the problem?
New iOS7+ solution optimized for Smoother Scrolling
You already can see old solutions but as far as huge amount of Apps will continue only iOS7+ support here is a way more optimized and correct solution.
Cell initialization
To initialize cell just call
dequeueReusableCellWithIdentifier
and iOS7+ systems are enough smart to handle ifcell == nil
or not. If during dequeue cell is nil system will automatically make a cell for you.Cell configuration
Then do your entire cell configuration in
willDisplayCell
method. Just create one method in your class that configures cell and here you go with better performance!