I am new to iphone development. I am using xCode 4.2 with storyboard. I am trying to get cells in my tableview to display several uilabels. They just aren't appearing in my simulator. but the original cell.textLabel is appearing.
here's what I did:
I created a new customcell.h/.m files that extend the UITableViewCell. I added some instance variables in the class. I went to the storyboard and in the class of the identity inspector of the tableviewcell, i changed it to point to customcell. I dragged and dropped some UIlabels into my new cell. I then went to the connection inspector to drag those "plus" icons with lines to connect to my new uilabels to my instance variables.
When I run my simulator, I don't see any of my new ui labels. I only see the original uilabel of cell.textLabel. I can programmatically get and set cell.mylabel1, cell.mylabel2 etc..., which are new labels, but hey just are not appearing.
Additioanl Details
This i the cellForRowAtIndexpath function for my tableviewcontroller.
static NSString *CellIdentifier = #"Cell"; // this was the error, i needed to change this to CustomCell, or whatever it is in my storyboard
CustomCell *cell = (CustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.mylabel1.text = #"hello"; // doesn't appear in simulator
cell.textLabel.text = #"world"; // does apepar in the simulator
As David has alluded, the one missing piece here is that you need to reference the Identifier of the cell specified in the Storyboard:
First, specify an identifier in the "Attributes Inspector" in the storyboard. You can do this by selecting the UITableViewCell and adding an identifier "ExampleCell" (for example). Second, reference this identifier in the code when creating the CustomCell.
static NSString *CellIdentifier = #"ExampleCell";
CustomCell *cell = (CustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Related
I am creating the cell programatically using the reuse identifier.
Note - I am not using storyboard for creating the cell
Whenever the cell is dequeued, the cell is nil, so the cell needs to be newly created using alloc, which is expensive.
EDIT (added 1 more question and corrected code)
Question
Why does this dequeue always return nil ? How can I correct it ?
Does dequeue work only when used along with storyboard / nib file ?
Code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell) //Every time cell is nil, dequeue not working
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
return cell;
}
You need to first set the CellIdentifier as Cell. Are you doing that? When you are creating a new cell you need to assign this identifier Cell to it. only then iOS will be able to dequeueReusableCellWithIdentifier with that identifier. Programatically you can do it like so -
UITableViewCell *cell = [[UItableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"Cell"];
You can set identifier from Interface Builder too -
I was making a couple of mistakes:
I was using a subclass of UITableViewController, but was creating the tableView outside of the subclass
There is a tableView created in the table view controller, which is self.tableView In the tableview controller while returning the cell for index path, I was using self.tableView instead of tableView.
Also, ensure that the cell identifier is declared as static
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Since tableView and self.tableView were representing different tables, the cell was not being dequeued from the same table and hence was always nil
This code should be generating the warning "control reaches end of non-void function" because you aren't actually returning anything. Add return cell; to the end of the function. Additionally, you never add the reuse identifier to the newly created cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
return cell;
}
First declare cell identifier for a tableViewCell at the viewDidLoad method as:
[tableView registerClass:UITableViewCell.class forCellReuseIdentifier:#"MyCell"];
Now recall the instance of the UITableViewCell with the same identifier "MyCell" as:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell" forIndexPath:indexPath];
Further just fill up the cell .. Now logic executes that limited number of cells are able to show enormously large list efficiently (using dequeue concept).
But remember to assign value (even nil if required) to every UIView used in the cell, otherwise overwriting / overlapping of text / images will happen.
I have a problem with my tableview. When I scroll and a cell disappears from the screen it becomes blank. I have built a prototype cell in the storyboard with two labels and one imageview, it have the same identifier that I use in my code. I also have built a custom class for the customcell. Here is the code in cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
Scientist *currentScientist = [[xmlParser data] objectAtIndex:indexPath.row];
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.self.cellName.text = currentScientist.self.name;
cell.self.cellSubject.text = currentScientist.self.subject;
cell.self.cellImage.image = currentScientist.self.image;
return cell;
}
I don't know if you need more code to help me.
In my case, creating a different cell identifier for each one worked just fine. I have something like:
NSString *cellIdentifier = [NSString stringWithFormat:#"identifier%i%i", indexPath.section, indexPath.row];
The rest should remain the same.
I found an article that details the problem you are encountering. I would also recommend printing out the Scientist data to ensure an object is being fetched correctly with the objectAtIndex:indexPath.row call.
From the article I linked below, I would be willing to bet that your dequeueReusableCellWithIdentifier is the problem. One quick way you could solve this is by giving each cell its' own unique cell identifier (Just to test out the theory). However, it looks the appropriate way to solve this is by changing up your cellForRowAtIndex method.
Source
I'm having a really weird issue with my custom UITableViewCell. I have a cell with an identifier of "ThreadCell" in Interface Builder with some custom labels. These labels are tagged so I can access them.
In my code, I am doing the following:
static NSString *CellIdentifier = #"ThreadCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: #"ThreadCell"];
}
Person *person = [self.people objectAtIndex: indexPath.row];
UILabel *nameLabel = (UILabel *)[cell viewWithTag: 0];
nameLabel.text = person.nickname;
return cell;
This seems to work fine, with one exception. The TableView draws like this:
This obviously isn't my custom cell. But the weird thing is, when I tap on a cell, I get this:
This is my custom cell, drawn behind the default cell. What?! I'm not sure how this is happening because I do not ever set the title of the textview anywhere, so I'm not sure where the first John Smith comes from.
Anyone have any ideas?
In your code, you allocate a plain UITableViewCell and not an instance of your custom cell. Setting a reuseIdentifier in initWithStyle is not sufficient to load an instance of a custom cell class.
If you develop for iOS 5 and later, then you can use registerNib:forCellReuseIdentifier: to register a NIB file containing your custom cell. dequeueReusableCellWithIdentifier: will then always return an instance of that NIB.
I have a tableview with custom cells via a uitableviewcell subclass. The cells have a label lblResult that changes after a a result is received. It works well, but, when I then scroll down my tableview, other random cells now have that same result label (but they still have their proper "name" label).
I figure this has to do with reuse identifiers, but I'm not sure.
Let me know if you need any more code to understand my problem.
The cell is made like this in cellForRowAtIndexPath
static NSString *CellIdentifier = #"tableCell";
FriendCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[FriendCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:nil];
}
Then before being returned, cell is passed into a loadingQueue dictionary.
When the result loads there is a resultComplete method which loads the cell from the loadingQueue dictionary and the following is called:
[[cell lblNumTagged] setText:[NSString stringWithFormat:#"(%d)",[thisDictionary count]]];
[[cell lblNumTagged] setHidden:NO];
Yes it is because cells are being re-used.
In your custom cell class you can use the prepareForReuse delegate method, which is being called before the cell is being reused and clear the cell's label there...
I know this is old but just in case. I think it is because when you create a new cell you are NOT specifying the identifier.
static NSString *CellIdentifier = #"tableCell";
FriendCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[FriendCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
Try it like this, note the end of the last line.....
I'm wondering if I could make a basic UITableView and statically set up everything using IB/Storyboarding in Xcode 4.2 but just one of the cells I want to display the current app version. (I'm making an about view) and I don't want to hardcode the app version because I know I'll forget to update it down the road. Is there any way to have that one cell get its data from the dataSource? I tried implementing
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
if (indexPath.section == 0 & indexPath.row == 0) {
cell.textLabel.text = [self appVersion];
}
return cell;
}
I've tried setting the cellIdentifier on all cells to #"Cell" as well as just setting it on the cell I care about modifying.
and only for that cell returning the app version but that wipes out the content of all the other cells.
If you are using a Static table in Storyboards the static table is the data source.
With a Static Table in Storyboard you would put a UILabel in the cell in question. Than setup a IBOutlet property in your View Controller and hook up the label to the outlet.
Then just update the label to your version number. You can hook up as many outlets as you want to different cells in a static table. Static table just means there is a fixed number of cells , you can still dynamically change the content of those fixed number of cells.
Use different ID for the first row.