cell properties returned nil - ios

I created a custom UITableViewCell named GateCell, inside it I placed one label and one text field.
In GateCell.h
#property (weak, nonatomic) IBOutlet UILabel *gateLabel;
#property (weak, nonatomic) IBOutlet UITextField *gateTextField;
In GateTableViewController
- (void)viewDidLoad {
[self.tableView registerClass:[GateCell class] forCellReuseIdentifier:#"cellIdentifier"];
}
Finally at cellForRowAtIndexPath method, I used like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
GateCell *cell = (GateCell *)[tableView dequeueReusableCellWithIdentifier:#"cellIdentifier"];
cell.gateLabel.text = #"Gate";
cell.gateTextField.text = #"Open Gate"
return cell;
}
When I print the description of the cell, I getting the following..
<`GateCell`: 0x7b6bd790; baseClass = `UITableViewCell`; frame = (0 0; 320 44); layer = <CALayer: 0x7b6c2e60>> <br>
Printing description of cell->_gateLabel:
nil
Printing description of cell->_gateTextField:
nil
Why label and textField returns nil when cell is created ???

I have previously encountered troubles when doing registerClass:forCellReuseIdentifier: and doing a dequeueReusableCellWithIdentifier: in tableView:cellForRowAtIndexPath:.
I had to replace dequeueReusableCellWithIdentifier: and directly init cells since registerClass:forCellReuseIdentifier: had been made.
Try in tableView:cellForRowAtIndexPath: this way
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//Create your custom cell GateCell the way it has to be done providing the 'reuseIdentifier'
//With a standard UITableViewCell it should be :
//UITableViewCell* cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cellIdentifier"];
GateCell *cell = [[GateCell alloc] init];
cell.gateLabel.text = #"Gate";
cell.gateTextField.text = #"Open Gate"
return cell;
}

First thing ensure that you connected the IBOutlet from the interface builder. if not then connect the IBOutlet.
for getting a cell use the following
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellReuseIdentifier"];

By calling
[self.tableView registerClass:[GateCell class] forCellReuseIdentifier:#"cellIdentifier"];
the table view will create a cell directly, not from a NIB file, so your IBOutlets won't be set (there is nowhere they could be set from).
Either you should be registering a NIB instead of a class or you should be creating the subviews as part of initWithStyle:reuseIdentifier:.
Your additional comments say that you're using a storyboard. In this case you should be setting the class of the cell you add in storyboard to GateCell and setting the cell identifier to cellIdentifier. Then, in code, you should remove the call to [self.tableView registerClass:[GateCell class] forCellReuseIdentifier:#"cellIdentifier"]; because making that call is replacing the storyboard registration...

Related

UITableViewCells get emptied on scroll (objc)

UITableViewCells get emptied on scroll (Objective-C)
I am having a problem with UITableViewCells getting emptied as soon I a start to scroll within the table view.
I already had a look at Cells become empty after scrolling. (Xcode) - however the problem still persists.
1) I have a popover view controller, which presents a way to log into some administration. Upon successful login (which hasn’t been implemented yet, the LOGIN button simply takes one straight to a test tableView - which should be fed from some external database later on).
2) Upon successful login, the login view inside the popover gets removed and a custom UITableViewController comes into play with its own XIB.
3) This UITableViewController uses a custom UITableViewCell - since prototype cells are not possible within this configuration.
It all works to the point where I scroll the table - and all the cells get emptied for some reason.
Here is the code run down (I leave out the obvious, eg properties and table section, etc setups):
1) customPopUpViewController(XIB ,.h, .m):
- (IBAction)loginButtonPressed:(UIButton *)sender {
UITableViewController *libraryTableViewController = [[LibraryAdminTableViewController alloc]initWithNibName:#"LibraryAdminTableViewController" bundle:nil];
libraryTableViewController.view.frame = CGRectMake(0, 179, libraryTableViewController.view.frame.size.width, libraryTableViewController.view.frame.size.height);
[self.view addSubview:libraryTableViewController.view];
}
2) LibraryAdminTableViewController (XIB ,.h, .m):
- (void)viewDidLoad {
[super viewDidLoad];
self.LibraryAdminTable.delegate = self;
self.LibraryAdminTable.dataSource = self;
self.tblContentList = [[NSMutableArray alloc]init];
self.tblContentList = [NSMutableArray arrayWithObjects:#"Sync Pack 1",#"Sync Pack 2",#"Sync Pack 3", nil];
[self.LibraryAdminTable registerNib:[UINib nibWithNibName:#"LibraryAdminTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:#"LibraryAdminCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
LibraryAdminTableViewCell *cell = [self.LibraryAdminTable dequeueReusableCellWithIdentifier:#"LibraryAdminCell" forIndexPath:indexPath];
NSString* trackList = [self.tblContentList objectAtIndex:indexPath.row];
cell.cellLabel.text = trackList;
return cell;
}
3) LibraryAdminTableViewCell (XIB ,.h, .m) - I gave the Identifier in the Attributes Inspector “LibraryAdminCell”:
#property (strong, nonatomic) IBOutlet UILabel *cellLabel;
What am I missing?
It is solved. According to this thread I had to get a strong reference to the custom UITableViewController via a property in the popup controller since the ViewController (being the DataSource for the tableView) would not be retained in memory.
This is happening because you are not creating a new cell, when tableview will try to dequeue a cell, and it does not get the cell, then it should create the cell to use but you are not creating any cell, so it is returning nil.Try the code below
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
LibraryAdminTableViewCell *cell = (LibraryAdminTableViewCell*)[self.LibraryAdminTable dequeueReusableCellWithIdentifier:#"LibraryAdminCell"
forIndexPath:indexPath];
if (cell == nil)
{
cell = [[LibraryAdminTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"LibraryAdminCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
NSString* trackList = [self.tblContentList objectAtIndex:indexPath.row];
cell.cellLabel.text = trackList;
return cell;
}

Need assistance understanding custom uitableviewcell initialization

While implementing custom UITableViewCell in tableView:cellForRowAtIndexPath: whats the difference between these two ways
loadNibNamed:owner:options:
and
SimpleTableCell *cell = [[SimpleTableCell alloc]init];
does loadNibNamed:owner:options: also alloc init? if not how SimpleTableCell will work without alloc init?
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
there is no explicit call of SimpleTableCell *cell = [[SimpleTableCell alloc]init];
OK, first off. I'm not actually going to answer the question at all. Instead I'll tell you how to create and use a custom UITableViewCell subclass. What you're doing at the moment isn't right.
Let's stick to the name SimpleTableCell that you have used.
Create the sub class
Create a subclass of UITableViewCell.
SimpleTableCell.h
#interface SimpleTableCell : UITableViewCell
// if coding only
#property (nonatomic, strong) UILabel *simpleLabel
// if from nib
#property (nonatomic, weak) IBOutlet UILabel *simpleLabel;
#end
SimpleTableCell.m
#import "SimpleTableCell.h"
#implementation SimpleTableCell
// if coding only
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//create the simpleLabel and add to self.contentView
}
return self;
}
// if from nib no need to do anything at all
// other stuff...
- (void)prepareForReuse
{
// empty the cell here.
// means you don't have to empty everything out in the controller
self.simpleLabel.text = #"";
}
#end
OK, so now we have a cell class.
Create the NIB if that's what you want
It looks like you're doing this already.
Create the nib with the same name (or not, doesn't really matter).
Make the top level item a UITableViewCell and set the subclass to SimpleTableCell. Now connect the outlets. In this example simpleLabel is all there is to connect.
Register the subclass with the table view
In the view controller that owns the table view. This means the table view can deal with creating and dequeueing the cells and you don't have to manually create them at all.
- (void)viewDidLoad
{
[super viewDidLoad];
// set up the other stuff...
// if coding only
[self.tableView registerClass:[SimpleTableCell class] forCellReuseIdentifier:#"SimpleCell"];
// if from a nib
UINib *cellNib = [UINib nibWithNibName:#"SimpleTableCell" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:cellNib forCellReuseIdentifier:#"SimpleCell"];
}
Now you just let the table deal with creating the cells. It keeps track of the reuse identifiers and cell queues so it can handle everything as normal. You just need to ask it to dequeue a cell for you with the identifier you registered you subclass for.
- (UITableViewCell*)tableView:(UITableView *)tableView cellFroRowAtIndexPath:(NSIndexPath *)indexPath
{
// This API was introduced in iOS6 and will ALWAYS return a valid cell.
// However, you need to register the class or nib with the table first.
// This is what we did in viewDidLoad.
// If you use a storyboard or nib to create a tableview and cell then this works too.
SimpleTableCell *mySimpleCell = [tableView dequeueReusableCellWithIdentifier:#"SimpleCell" forIndexPath:indexPath];
mySimpleCell.simpleLabel.text = #"Hello, World";
return mySimpleCell;
}
EDIT
You can create a cell (indeed any class) using...
SimpleTableCell *cell = [[SimpleTableCell alloc] init];
But doing it this way means it isn't associated to a table view or part of a queue.
One step down (if you like) from the method in my answer is to use the old dequeuReusableCell... method and then to check if it's nil and create it like this...
- (UITableViewCell*)tableView:(UITableView *)tableView cellFroRowAtIndexPath:(NSIndexPath *)indexPath
{
// Old way, don't do this if you're targeting iOS6.0+
SimpleTableCell *mySimpleCell = [tableView dequeueReusableCellWithIdentifier:#"SimpleCell"];
if (!mySimpleCell) {
// have to use initWithStyle:reuseIdentifier: for the tableView to be able to dequeue
mySimpleCell = [[SimpleTableCell alloc] initWithStyle:UITableViewCellStyleCustom reuseIdentifier:#"SimpleCell"];
}
mySimpleCell.simpleLabel.text = #"Hello, World";
return mySimpleCell;
}
I'm not even sure you can load from a nib in here as you wouldn't be able to set the reuse identifier on the cell.
Multiple cell subclasses
OK, last edit :D
For multiple UITableViewCell subclasses you can use this too. I have done exactly this in the past. You might, for instance, have a cell for a Post item a cell for an Image item a cell for a Comment item etc... and they are all different.
So...
- (void)viewDidLoad
{
// the rest
// register each subclass with a different identifier
[self.tableView registerClass:[PostCell class] forCellReuseIdentifier:#"PostCell"];
[self.tableView registerClass:[ImageCell class] forCellReuseIdentifier:#"ImageCell"];
[self.tableView registerClass:[CommentCell class] forCellReuseIdentifier:#"CommentCell"];
}
To help keep this small (and it comes in handy for NSFetchedResultsControllers too, I move the configuration of the cell out to another method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
if (the required cell is a post cell) {
cell = [tableView dequeueReusableCellWithIdentifier:#"PostCell" forIndexPath:indexPath];
[self configurePostCell:(PostCell *)cell atIndexPath:indexPath];
} else if (the required cell is a image cell) {
cell = [tableView dequeueReusableCellWithIdentifier:#"ImageCell" forIndexPath:indexPath];
[self configureImageCell:(ImageCell *)cell atIndexPath:indexPath];
} else if (the required cell is a comment cell) {
cell = [tableView dequeueReusableCellWithIdentifier:#"CommentCell" forIndexPath:indexPath];
[self configureCommentCell:(CommentCell *)cell atIndexPath:indexPath];
}
return cell;
}
- (void)configurePostCell:(PostCell *)postCell atIndexPath:(NSIndexPath *)indexPath
{
// get the object to be displayed...
postCell.postLabel = #"This is the post text";
postCell.dateLabel = #"5 minutes ago";
}
- (void)configureImageCell:(ImageCell *)imageCell atIndexPath:(NSIndexPath *)indexPath
{
// get the object to be displayed...
imageCell.theImageView.image = //the image
imageCell.dateLabel = #"5 minutes ago";
}
- (void)configureCommentCell:(CommentCell *)commentCell atIndexPath:(NSIndexPath *)indexPath
{
// you get the picture...
}
loadNibNmed:... is asking the system to recreate an object (usually, but not limited to a UIView) from a canned instance in a nib file. The nib file is created using the interface builder portion of Xcode.
When an object is loaded from a nib file (loadNibNamed...) init doesn't get called, instead initWithCoder: gets called. If you're looking to do post initialization setup on a view loaded from a nib file, the usual method is to awakeFromNib and call [super awakeFromNib]

Nested UITableView not returning any cells

I have a UITableView which has another UITableView nested inside one its cells (I know this is bad practise, don't worry!).
The problem is that when I call dequeueReusableCellWithIdentifier: I am getting nil back. HOWEVER this works just fine when the UITableView is not nested inside another one.
Is there a way to NOT reuse a UITableViewCell, but instead directly instatiate it every time?
I've tried using this:
ContactFieldCell *cell = [[ContactFieldCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:thisCellIdentifier];
which doesn't return nil, but then nothing appears in my UITableView!
Here's the code for the "parent" UITableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ContactCardCell";
ContactCardCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSArray *objects = [[sections objectAtIndex:indexPath.section] objectForKey:#"objects"];
CDCard *card = [objects objectAtIndex:indexPath.row];
cell.delegate = self;
cell.fieldsTableView = [[CardTableViewController alloc] initWithCard:card];
[cell.fieldsTableView.view setFrame:CGRectMake(17, 12, 256, 163)];
[cell.contentView addSubview:cell.fieldsTableView.view];
return cell;
}
and here's the code for the "child" UITableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *thisCellIdentifier = #"ContactFieldCell";
ContactFieldCell *cell = [self.tableView dequeueReusableCellWithIdentifier:thisCellIdentifier];
cell.delegate = self;
cell.field = [self.card.sortedFields objectAtIndex:indexPath.row];
return cell;
}
ContactFieldCell is a prototype cell within the storyboard. It has the following code:
#interface ContactFieldCell : UITableViewCell
#property (nonatomic, weak) id<ContactFieldCellDelegate> delegate;
#property (nonatomic, strong) CDField *field;
#property (nonatomic, strong) IBOutlet UILabel *displayNameLabel;
#end
dequeueReusableCellWithIdentifier: does not create a cell if none was found for dequeueing.
Create a cell manually, or use dequeueReusableCellWithIdentifier:forIndexPath:
Yes - #vikingosegundo is correct, but to expand his answer, you need to also register your cell first. dequeueReusableCellWithIdentifier: may return nil. And if it is you need to create your cell,s but dequeueReusableCellWithIdentifier: forIndexPath: will always return a valid cell, the catch is you need to tell it what kind of cell, that is what registerClass does.
Do this for both UITableViews.
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[ContactFieldCell class] forCellReuseIdentifier:#"ContactFieldCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *thisCellIdentifier = #"ContactFieldCell";
ContactFieldCell *cell = [self.tableView dequeueReusableCellWithIdentifier:thisCellIdentifier forIndexPath:indexPath];
cell.delegate = self;
cell.field = [self.card.sortedFields objectAtIndex:indexPath.row];
return cell;
}
UITableViews are a very powerful element and can be used to build great apps.
The only thing to keep in mind is, the basics must be clear. Now from your code, I cannot make out whether you have assigned the delegates and dataSources properly, but I'll still mention it in case someone else needs it.
You have a subclassed UITableViewCell which in turn contains a UITableView. The UIViewController must be the delegate and dataSource for the outer UITableView. Make sure you have set it in both the .h and .m file.
Next, your custom cell must also be the delegate and dataSource, but for the inner UITablewView. I suppose here, you have created the inner UITableView in the init method of the UITableViewCell. Set the delegate and dataSource there itself. Then you set other runtime properties in the drawRect method (if needed) and call it's reloadData.
The UIViewController must override the delegate and dataSource methods for the outer table and the cell must override the methods for the inner table.
Also, make sure, the time the cells are plotted, your data is not nil or null.
And a very important fact, that people miss is the following code:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
Just dequeueing the cell is not enough. The first time a cell is dequeued, it is nil because it has not been created yet. Hence the if condition. Once it is allocated and initialized and added to the table, the dequeue code works thereafter.
NOTE : After looking more closely to your code (sorry for not looking the first time), I noticed you have allocated a UITableViewController to your cell. How do you think the cell is going to display a controller? Use a UITableView instead. Try to follow the pattern I have mentioned in paragraph 3. Use a table in the custom cell as a private member (or property, your wish), allocate it in init. Assign the data to the cell from your view controller. Then use this data to set the inner table view cell's properties in it's drawRect. It should work fine.

Why am I getting an error about being unable to dequeue when my UITableView tries to load?

I get the following error:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell
with identifier FontCell - must register a nib or a class for the
identifier or connect a prototype cell in a storyboard'
I'm not sure exactly what I'm doing wrong. I set the cell identifier (programmatically, as it's not created through Interface Builder) and do everything I thought I was supposed to do in the delegate methods, but I'm still getting that error when I try to get the UITableView to load.
Here's the relevant code (it's worth noting I've subclassed UITableViewCell for customization options):
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.fonts.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"FontCell";
FontCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (!cell) {
cell = [[FontCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"FontCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
int row = indexPath.row;
cell.fontFamilyLabel.text = self.fonts[row];
return cell;
}
And here's the only method I changed in my subclassed UITableViewCell (FontCell):
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.fontFamilyLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, 200, 20)];
self.fontFamilyLabel.textAlignment = NSTextAlignmentCenter;
[self.contentView addSubview:self.fontFamilyLabel];
}
return self;
}
What exactly am I doing wrong?
Easiest fix is to just change it to FontCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; As with your current code, you'll have to check to be sure cell is not nil if you do this method.
Alternately, you can register a UINib or Class at the table level that is tied to #"FontCell"
For example (up in viewDidLoad):
[self.tableView registerClass: [FontCell class] forCellReuseIdentifier:#"FontCell"];
Then you can do
FontCell *cell = [tableView dequeueReusableCellWithIdentifier:#"FontCell" forIndexPath:indexPath];
The nice thing with this method is that you know that your cell will never be nil, so you can just immediately begin modifying it.
You're using the dequeueReusableCellWithIdentifier:forIndexPath: method. The documentation for that method says this:
You must register a class or nib file using the registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier: method before calling this method.
So here
[self.tableView registerClass: [FontCell class] forReuseIdentifier: #"FontCell"];
I also had such a problem, and the solution I found is:
Go to the Project Navigator and select “ViewController.h”. Append
<UITableViewDelegate, UITableViewDataSource>
after “UIViewController”.
If using a tableview (not a table view controller) as I was, there are not cells that appear by default.
In the storyboard select the tableview
Open the Attributes inspector
Change prototype cells from 0 to 1
Select the newly displayed table cell
In the Attributes inspector set the Identitifier to "FontCell"

IOS Static Table with Custom Cell only draws a random cell

I am trying to create a "settings" table view for my app. I am trying to mimic it to be the same style as the gneral setting on an Iphone. I have created my own custom cell class by inheriting from UITableCell. I gave it the appropriate IBOulets and i have hooked them up in the storyboard. I also hooked up the switch to my tableViewControler, but for some reason my code is only returning me one empty cell (it being only one cell is not an issue atm for that's all i have in my setting). I triple checked and made sure that I'm using the same cell identifier in my code and in storyboard. Anyone know why I'm getting a blank cell back?
Here is my .h file for my custom cell.
#interface NHPSettingsCell : UITableViewCell
#property (nonatomic,weak) IBOutlet UILabel *settingLabel;
#property (nonatomic,strong) IBOutlet UISwitch *settingSwitch;
#end
MY Problem code is here, my .h file for the custom cell:
#import "NHPSettingsCell.h"
#implementation NHPSettingsCell
#synthesize settingLabel, settingSwitch;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
My method for drawing the cell in my custom view controller:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SettingsCell";
NHPSettingsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[NHPSettingsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellStyleDefault;
}
cell.settingLabel.text = #"firstSetting";
//check the if user wants promt of disclaimer each time or not.
if([prefs boolForKey:#"firstSetting"] == YES){
cell.settingSwitch.on = YES;
}else{
cell.settingSwitch.on = NO;
}
return cell;
}
Now the thing that annoys me is i have successfully managed to implement the cellForRowAtIndexPath method for a dynamic table that uses custom cells. I have also implements the code for a static table using the default cell, but for a static table with custom cells it just doesn't seem to work. Here is the code on how I implemented my custom cells on a dynamic table (note how i didn't have to init the cells but it works).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"InteractionResultCell";
NHPResultCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure & Fill the cell
cell.leftLabel.text = [[resultsList objectAtIndex:indexPath.row] substanceName];
cell.rightLabel.text = [[resultsList objectAtIndex:indexPath.row] substanceName2];
NSString *color = [NSString stringWithFormat:#"%#", [[resultsList objectAtIndex:indexPath.row] color]];
//Change a hex value to a readable 0x number to pass ot hte macro so we can go from a hex color to a RGB system.
NSScanner *scanner;
unsigned int tempint=0;
scanner = [NSScanner scannerWithString:color];
[scanner scanHexInt:&tempint];
cell.severityButton.backgroundColor = UIColorFromRGB(tempint);
return cell;
}
Two problems:
If you are using static cells, do not implement any datasource methods in your view controller (numberOfRows, numberOfSections, cellForRow...) as this will override what you have built in the storyboard. The table has the sections, rows and content you give it in the storyboard.
Cells loaded from the storyboard (either dynamic prototypes, or static cells) are initialised using initWithCoder:, not initWithStyle:. awakeFromNib: is a better place to put your set up code.
dequeueReusableCellWithIdentifier: works only if a cell has already been created to prevent repeated memory allocations. You cannot reuse a cell without creating it first. The static cells created in the xib are the default type. That's why it doesn't work for static table with custom cells. Add the cell creation code after reuse as you've done in your custom view controller's cellForRowAtIndexPath: method:
if (cell == nil) {
cell = [[NHPSettingsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellStyleDefault;
}
EDIT- To init your custom cell, you'll have to load from xib. Add the following class method to your NHPSettingsCell.m:
+(NHPSettingsCell*) createTextRowWithOwner:(NSObject*)owner{
NSArray* wired = [[NSBundle mainBundle] loadNibNamed:#"NHPSettingsCell" owner:owner options:nil];
NHPSettingsCell* cell = (NHPSettingsCell*)[wired firstObjectWithClass:[NHPSettingsCell class]];
return cell;
}
and then call it from your custom view controller as:
cell = (NHPSettingsCell*)[tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (Nil == cell) {
cell = [NHPSettingsCell createTextRowWithOwner:self];
}

Resources