Prototype cell from storyboard not creating UILabe

2020-07-09 08:49发布

问题:

My question is very similar to this one.
My custom prototype cells designed in Interface Builder using storyboards have all the internal objects set to nil (not created), so when I try to assign values to them, they remain blank.

I am using Xcode 4.6.2, and running the code in the 6.1 iPhone simulator. Here is what I've done:

  • designed a prototype cell in interface builder with the necessary fields.
  • created a subclass of UITableViewCell for this custom cell in code, and then set the cell in interface builder to this type.
  • control-dragged the fields into the .h file, which set up the objects (UILabels, etc) for me. I set the identifier of the cell to "serverNameCell"
  • set the datasource & delegate of the table to the Viewcontroller that the table is in.
  • associated the table with a table object in the ViewControler

At the moment, the table displays with the correct number of sections & rows, but the values of the cell are not being set.

This is the cellForRowAtIndexPath:(NSIndexPath *)indexPath code:

NewServerCell *cell = [tableView dequeueReusableCellWithIdentifier:@"serverNameCell"];

I always get back a cell, and the memory location seems to be ok for a valid object.

But when I try to cell.name.text = [thisServer name]; I find that the cell.name label is always nil.
There are no crashes - but my fields are not being set.

I have checked a million times that the identifier is ok - it is! I have gone through the Apple documentation for custom cells from a storyboard - but still get this frustrating issue..

Anyone else had this, and resolved it?

回答1:

I had this exact problem today with Xcode 5's storyboard. After pulling almost all my remaining hair out, I noticed I was calling this in viewDidLoad:

[self.tableView registerClass:[SwitchTableViewCell class] forCellReuseIdentifier:@"Setting"];

Whoops! This line is unnecessary when using prototype cells in storyboards. The storyboard automatically configures this for me. SwitchTableViewCell *tableViewCell = [tableView dequeueReusableCellWithIdentifier:@"Setting" forIndexPath:indexPath]; works just fine without calling registerClass:: explicitly.

The question still remains of why calling registerClass:: causes some outlets to not be connected.



回答2:

An easy workaround for this problem is to tag the UILabel in the prototype and manipulate it with:

UILabel* label = [cell viewWithTag:cellTag];
label.text = [thisServer name]



回答3:

Here is the most obviously missed reason (I do it all the time!):

Did you set the delegate and datasource of your tableview to the controller? (i.e. self)

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    _tableView.delegate = self;
    _tableView.dataSource = self;
}


回答4:

Hope you have already got a fix for this issue. Anyways since I do not see a straight forward answer to your issue, I am writing this down.

From my experience in the case of using custom Prototype cell in storyboards, provide the indexPath as well. Use the following method:

MyCustomCell *cell = (MyCustomCell *)[tableView dequeueReusableCellWithIdentifier:@"CellIdentifier" forIndexPath:indexPath];

instead of this code:

NewServerCell *cell = [tableView dequeueReusableCellWithIdentifier:@"serverNameCell"];

Changing this will readily fix this issue. You will see all hooked up labels and image views with their values visible on the tableview.



回答5:

Scratched my head way too hard on this one. Ended up being that I was declaring my IBOutlets with retain instead of strong in my CustomUITableViewCell.h file. I guess I need to research more into memory management.

Wrong:

@property (nonatomic, retain) IBOutlet UIImageView  *preview;

Correct:

@property (nonatomic, strong) IBOutlet UIImageView  *preview;


回答6:

check how you`re initializing your TableViewController. I had the same problem, then I figured that I was not referencing my TableViewController appropriately.

So i had to change my code before the "pushViewController".

Instead of : [[TableViewController alloc]init] use : [self.storyboard instantiateViewControllerWithIdentifier:yourTableViewIdentifier]

and dont forget to REMOVE any code registering cell classes for your tableview like : [self.tableView registerClass:[SwitchTableViewCell class] forCellReuseIdentifier:@"Setting"];

Hope it helps



回答7:

Some stuff to try:

It sounds like you know what you're doing but I'll mention the obvious just to remind you. Make sure the "name" property is set to IBOutlet.

  • In IB you can set the class type for files owner, Set this to your custom class.

  • Just for sake of troubleshooting take out the dequeue stuff temporarily and try it.

  • Try another property name other than "name" I dont believe "name" exists in baseclass though.

I've run into similar things like this before, it's probably something simple.



回答8:

I also had the exact same problem (labels were nil in the cell).

My remedy was to remove an initWithCoder method that I "accidentally" added to the table view while trying out other stuff. This method is called when the cell gets initiated from the storyboard. If you overwrite it and don't take care of initiating all labels inside of it yourself you will end up with nil labels.

So, as one potential error for this symptom: Check for presence of this method.

-(id)initWithCoder:(NSCoder *)decoder {
    self = [self init];
    return self;
}