UITableViewCell doesn't show it's content - ios

I am working a UITableViewController with a dynamic TableView, which displays some information about a dish. Everything is working fine, but one cell just stays blank.
When I debug the code, all things look like expected (tableView:cellForRowAtIndexPath: gets called for each portion in self.menuItem.menuPortions, portion isn't nil and values of it's properties are valid, the UILabels aren't nil either), but the first portionCell stays empty, no matter how much portions self.menuItem.menuPortions holds...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
switch (indexPath.section) {
case 0:{//image
cell = [tableView dequeueReusableCellWithIdentifier:#"imageCell" forIndexPath:indexPath];
UIImageView* imageView = ((UIImageView*)[cell viewWithTag:1]);
[self.menuItem setImageOfImageView:imageView OrDeleteCellAtIndexPath:indexPath fromTable:tableView];
break;}
case 1:{//description
cell = [tableView dequeueReusableCellWithIdentifier:#"descriptionCell" forIndexPath:indexPath];
UITextView * descriptionTextView = (UITextView*)[cell viewWithTag:1];
descriptionTextView.text = self.menuItem.menuItemDescription;
break;}
case 2:{//portions
cell = [tableView dequeueReusableCellWithIdentifier:#"portionCell" forIndexPath:indexPath];
id<MenuItemPortionProtocol> portion = self.menuItem.menuPortions[indexPath.row];
UILabel * sizeLabel = (UILabel*)[cell viewWithTag:1];
sizeLabel.text = portion.size;
UILabel * priceLabel = (UILabel*)[cell viewWithTag:2];
priceLabel.text = [portion priceString];
break;}
case 3:{//categories
cell = [tableView dequeueReusableCellWithIdentifier:#"categoriesCell" forIndexPath:indexPath];
UILabel* categoriesLabel = (UILabel*)[cell viewWithTag:1];
categoriesLabel.text = [self.menuItem.categories componentsJoinedByString:#", "];
break;}
default:
break;
}
// Configure the cell...
return cell;
}
Does someone have a hint, what goes wrong?

Related

UITableView not scrolling after i did this

I'm new to iOS developing. I have a UITableViewCell which has three buttons and they were not appearing to be pressed to touch. I implemented the following code. The pressing appeared to have been solved but the scrolling have been disabled. Here's my code to make buttons appear to be pressed on touch. The loop in the code is important otherwise the table will not behave the way I want it to. Here's my code for cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSString *CellIdentifier = #"customCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UILabel *textLabel = (UILabel *) [cell.contentView viewWithTag:5];
switch ([indexPath section]) {
case 0:
textLabel.text = [patientRoom objectAtIndex:[indexPath row]];
break;
case 1:
textLabel.text = [patientsBathroom objectAtIndex:[indexPath row]];
break;
}
if (shown){
if (selectedIndexPath.row == indexPath.row)
comments.hidden = NO;
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
// Configure the cell...
for (id obj in cell.subviews){
if ([NSStringFromClass([obj class]) isEqualToString:#"UITableViewCellScrollView"]){
UIScrollView *scroll = (UIScrollView *) obj;
scroll.delaysContentTouches = NO;
break;
}
}
return cell;
}

TableView Cell Custom type Text Overlaps itself or is Blank

Hoping someone can advise me on the correct method to populate a UITableViewCell with custom labels. I keep running into the same issues , either the label is blank or when the table fills up with cells reused ones show overlapping label text.
I have followed what has been advised for others here but each way I do it something breaks.
** Update **
I have changed the code to below and have most of it working except when I select a cell the label overlaps as in the screenshot below. The code for the tutorial I am using can be found here: https://github.com/funkyboy/Core-Data-on-iOS-5-Tutorial--How-To-Work-with-Relations-and-Predicates
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
FailedBankInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];
CGRect infoFrame = CGRectMake(10, 10, 200, 16);
UILabel *infoLabel = [[UILabel alloc] initWithFrame:infoFrame];
infoLabel.textColor = [UIColor blackColor];
infoLabel.backgroundColor = [UIColor yellowColor];
infoLabel.font = [UIFont systemFontOfSize:12];
infoLabel.textAlignment = NSTextAlignmentCenter;
infoLabel.tag = indexPath.row;
infoLabel.text = [NSString stringWithFormat:#"%#, %#", info.city, info.state];
[cell addSubview:infoLabel];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
FailedBankInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];
UILabel *theLabel = (UILabel *)[cell.contentView viewWithTag:indexPath.row];
theLabel.text = [NSString stringWithFormat:#"%#, %#",
info.city, info.state];
}
Because I am using the Prototype Cell with Core Data and fetchedresultcontroller the if(!cell) is never called. I changed the tag to be the indexPath.row number. Every tutorial I have followed works fine if you use the predefined cell types. If I use Custom with my own labels it never works out. Should I not use a fetchedresultscontroller for the tableview data? If I change the city title in the detail view and save it the following code gets called:
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray
arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray
arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
Here are some screenshots:
***Update - When using custom cells remove the prototype cell as you don't need it!!
I finally figured out why it was not working. The whole problem is the Prototype Cell because you have to set a reuse Identifier and in most of the tutorials they use the string "Cell".
When the tableview load it already has a cell in it with the Identifier "Cell" so it doesn't create a new cell it just reuses the cell that has the Identifier "Cell".
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
The above block if (cell == nil) is never called because it is reusing the Prototype cell that is already there. The other problem is creating the label below this block as in:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
FailedBankInfo *info = [_fetchedResultsController objectAtIndex:indexPath.row];
CGRect infoFrame = CGRectMake(10, 10, 200, 16);
UILabel *infoLabel = [[UILabel alloc] initWithFrame:infoFrame];
infoLabel.textColor = [UIColor blackColor];
infoLabel.backgroundColor = [UIColor yellowColor];
infoLabel.font = [UIFont systemFontOfSize:12];
infoLabel.textAlignment = NSTextAlignmentCenter;
infoLabel.tag = 101;
infoLable.text = [NSString stringWithFormat:#"%#, %#",
info.city, info.state];
[cell.contentView addSubview:infoLabel];
return cell;
}
This appears to work fine as it does create the Label but when you scroll the screen you find that Labels are overlapping themselves as in my problem. This is because when a cell goes off screen and comes back on the cellForRowAtIndexPath reuses a cell that already has a label and creates another Label over the top. This keeps happening until you have 7, 8 or more Labels overlapping on the same cell. I worked this out by putting an NSlog in the didSelectRowatIndex to count the number of subviews here:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Count is:%i", [[tableView cellForRowAtIndexPath:indexPath].contentView.subviews count]);
}
So what you need to do is create the custom Label inside the if (cell == nil) and use an else to only set the text of the Label. The key for this to work is that each cell has to have a unique reuse Identifier so when CellforRowatIndexPath is called it creates a new cell the first time it appears. When that cell goes off screen and comes back on a new cell is not created it just reuses the existing one and changes the text without creating another Label. I have checked this with another NSlog in the if (cell == nil) it fires once for each cell and after that it doesn't fire because it reuses dequeued cells. I just used a string "myCell" + indexPath.row for the Identifier. In the storyboard I still have the Identifier of "Cell" for the Prototype cell. It complains if you don't have something in there. Here is my final code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *myCellID = [NSString stringWithFormat:#"myCell%i", indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:myCellID];
FailedBankInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:myCellID];
CGRect infoFrame = CGRectMake(10, 10, 200, 16);
UILabel *infoLabel = [[UILabel alloc] initWithFrame:infoFrame];
infoLabel.textColor = [UIColor blackColor];
infoLabel.backgroundColor = [UIColor yellowColor];
infoLabel.font = [UIFont systemFontOfSize:12];
infoLabel.textAlignment = NSTextAlignmentCenter;
infoLabel.tag = 101;
infoLabel.text = [NSString stringWithFormat:#"%#", info.name];
[cell.contentView addSubview:infoLabel];
}
else {
UILabel *theLabel = (UILabel *)[cell viewWithTag:101];
theLabel.text = [NSString stringWithFormat:#"%#", info.name];
}
return cell;
}
Also I am still using the code:
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
FailedBankInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];
UILabel *theLabel = (UILabel *)[cell viewWithTag:101];
theLabel.text = [NSString stringWithFormat:#"%#", info.name];
}
To update the label text when the Core data object changes with the following code:
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray
arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray
arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
I also found sometimes when segueing back to the table view the table doesn't always update so to fix this you can use:
-(void) viewWillAppear {
[self.tableView reloadData];
}
Thanks for all of your input it did help me come to a solution and I hope that this helps anyone else who is experiencing the same issue. I think I have explained it well enough. I'm not an expert by any means. Just another guy trying to build an App :)
I just fixed it with just 2-3 lines of code. This is happening because When tableView display your content by using this.
[cell.contentView addSubView:myView];
Now it will work perfectly if your tableView is not Scrolling but when you scroll your TableView then it overlap the content because it will not clear old content from memory and you can see memory usage in Memory Debug Session. Now your Memory Consumption will be Increasing with scrolling.
So the Best Solution is to Clear all the old Content from Cell's contentView First before adding new Content to Cell Memory. So that It will run Smoothly.
I have used following code for Clearing old memory from Cell's contentView before adding any Content to contentView.
for (id object in cell.contentView.subviews)
{
[object removeFromSuperview];
}
I think this is the Perfect Solution. But I still need Reviews from you Guys. Please share your Experience.
For storyboards create custom cell class as below.Set your labels visually and set required properties like color,font,size etc
myCell.h
#import <UIKit/UIKit.h>
#interface myCell : UITableViewCell
//connect your labels and image as below
#property (weak, nonatomic) IBOutlet UIImageView *myImage;
#property (weak, nonatomic) IBOutlet UILabel *myLabel1;
#property (weak, nonatomic) IBOutlet UILabel *myLabel2;
#property (weak, nonatomic) IBOutlet UILabel *myLabel3;
#end
yourViewController.m
//Set up your custom cell
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"Cell";
myCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[myCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.myLabel1.text = #"hello1";
cell.myLabel2.text = #"hello2";
cell.myLabel3.text = #"hello3";
[cell.myImage setImage:[UIImage imageNamed:#"google.jpg"]];
return cell;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
FailedBankInfo *info = [_fetchedResultsController objectAtIndex:indexPath.row];
CGRect infoFrame = CGRectMake(10, 10, 200, 16);
UILabel *infoLabel = [[UILabel alloc] initWithFrame:infoFrame];
infoLabel.textColor = [UIColor blackColor];
infoLabel.backgroundColor = [UIColor yellowColor];
infoLabel.font = [UIFont systemFontOfSize:12];
infoLabel.textAlignment = NSTextAlignmentCenter;
infoLabel.tag = 101;
infoLable.text = [NSString stringWithFormat:#"%#, %#",
info.city, info.state];
[cell.contentView addSubview:infoLabel];
return cell;
}
I had this kind of problems with tableview many times before. The best solution I found so far is creating my own "reuseTableViewCellWithIdentifier" method (in myViewController.m) and then using it to get the cell in "cellForRowAtIndexPath method".
In your case it will be like this :
-(UITableViewCell *)reuseTableViewCellWithIdentifier:(NSString *)identifier withIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell =[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
FailedBankInfo *info = [_fetchedResultsController objectAtIndex:indexPath.row];
CGRect infoFrame = CGRectMake(10, 10, 200, 16);
UILabel *infoLabel = [[UILabel alloc] initWithFrame:infoFrame];
infoLabel.textColor = [UIColor blackColor];
infoLabel.backgroundColor = [UIColor yellowColor];
infoLabel.font = [UIFont systemFontOfSize:12];
infoLabel.textAlignment = NSTextAlignmentCenter;
infoLabel.tag = 101;
infoLabel.text = [NSString stringWithFormat:#"%#, %#", info.city, info.state];
[cell.contentView addSubview:b];
return cell;
}
Now you just need to get the Label with its tag and change its value in your cellForRow method like this :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (nil == cell) {
cell = [self reuseTableViewCellWithIdentifier:CellIdentifier withIndexPath:indexPath];
}
UILabel *infoLabel = (UILabel *)[cell.contentView viewWithTag:101];
FailedBankInfo *info = [_fetchedResultsController objectAtIndex:indexPath.row];
infoLabel.text = [NSString stringWithFormat:#"%#, %#", info.city, info.state];
return cell;
}
I had the same issue.I think this is because we are reusing the identifier so cells are overlapped on others. The below lines of code worked for me..
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:nil];
You just need to tick clears Graphic context in the property section of that label in storyboard.

TableView repeats first 13 rows

I've got an UITableView with 30 objects.
Controller shows correctly first 13 rows, on 14th row use a "joker" row which changes his content scrolling, then start again with first thirteen row and "joker" row until the end.
That's code of cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: #"cell" forIndexPath:indexPath];
UIImageView * flagImageView = (UIImageView *) [self.view viewWithTag:1];
UILabel * nationLabel = (UILabel *) [self.view viewWithTag:2];
nationLabel.text = [_nationsArray objectAtIndex:indexPath.row];
nationLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
NSLog(#"%i", indexPath.row);
return cell;
}
Strange thing is that configuring cell in if (cell == nil) { ... } it doesn't work...
The problem seems to be with the nationLabel. When I replaced
UILabel * nationLabel = (UILabel *) [self.view viewWithTag:2];
nationLabel.text = [_nationsArray objectAtIndex:indexPath.row];
with
cell.textLabel.text = [_nationsArray objectAtIndex:indexPath.row];
it's working fine (at least the text). So I think you should try to make a UITableViewCell subclass, make property for that label and see if it's ok then.
Don't use this
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: #"cell" forIndexPath:indexPath];
Change your code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: #"cell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
UIImageView * flagImageView = (UIImageView *) [self.view viewWithTag:1];
UILabel * nationLabel = (UILabel *) [self.view viewWithTag:2];
nationLabel.text = [_nationsArray objectAtIndex:indexPath.row];
nationLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
NSLog(#"%i", indexPath.row);
return cell;
}

Searchbar works correctly but doesn't show any results

I've added a search bar to my project and it works quite well. You can search for object (of a table view) and the relations also work. But the search display doesn't show the result names.
For example: I have no object which begins with "x" >>> So no result (That's correct):
But one object starts with "b", but the name isn't displayed although I can click on it and it shows me the next view (Relation) correctly:
Maybe this is caused due to my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"CarCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
Car *search = [searchResults objectAtIndex:indexPath.row];
UILabel *carNameLabel = (UILabel *)[cell viewWithTag:101];
carNameLabel.text = search.name;
I don't know why this doesn't work and this seems to be very strange to me.
It would be great if someone can help me.
Update: Full method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"CarCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
Car *search = [searchResults objectAtIndex:indexPath.row];
UILabel *carNameLabel = (UILabel *)[cell viewWithTag:101];
carNameLabel.text = search.name;
} else {
Car *car = [cars objectAtIndex:indexPath.row];
UIImageView *carImageView = (UIImageView *)[cell viewWithTag:100];
carImageView.image = [UIImage imageNamed:car.thumbnail];
UILabel *carNameLabel = (UILabel *)[cell viewWithTag:101];
carNameLabel.text = car.name;
UILabel *carSpeedLabel = (UILabel *)[cell viewWithTag:102];
carSpeedLabel.text = car.carSpeed;
}
return cell;
}
You're attempting to fetch the UILabels that you're setting by tag values, but you're using a stock UITableViewCell. Try the following:
if (tableView == self.searchDisplayController.searchResultsTableView) {
Car *search = [searchResults objectAtIndex:indexPath.row];
cell.textLabel.text = search.name;
} else {
Car *car = [cars objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:car.thumbnail];
cell.textLabel.text = car.name;
cell.detailTextLabel.text = car.carSpeed;
}
If you don't want to use the standard UIViews that are built into a normal UITableViewCell, you'll have to create and add your custom views (and set their tag property) in the block where you create new cells.
If the updated code is the entire tableView:cellForRowAtIndexPath: method then you didn't add the carImageView, carNameLabel, and carSpeedLabel views to your cell.
You need to add and configure those subviews, including with the appropriate tags, when you initialize a new cell. You should add the views to cell.contentView and then use [cell.contentView viewWithTag:X] to retrieve them.

iOS: UITableView mixes up data when scrolling too fast

I've subclassed the UITableViewCell to add custom appearance to it. At the init level of the MYTableViewCell I added 4 subviews: UIImageView, and three UILabel(s). All 4 subviews have a different Tag assigned to them.
Inside the cellForRowAtIndexPath method I either create a new cell if it wasn't available at first, or reuse available one and assign the proper text to the ui labels.
The problem I am having is that if I try to scroll super fast, then the data gets messed up, however if I scroll up and down more slowly, then everything works fine.
Any thoughts??
Below is the code:
- (MyTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"itemListTableViewCell";
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
DisplayableEntity *displayableEntity = [self.fetchedResultsController objectAtIndexPath:indexPath];
if( ! cell ) {
cell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
[self tableView:tableView appearanceForCell:cell withEntity:displayableEntity];
} else {
UIImageView *imageView = (UIImageView *) [cell viewWithTag:IMAGEVIEW_TAG];
imageView.image = [UIImage imageNamed:displayableEntity.displayImageName];
UILabel *titleLabel = (UILabel *) [cell viewWithTag:TITLEVIEW_TAG];
titleLabel.text = displayableEntity.entityName;
UILabel *itemDescription = (UILabel *) [cell viewWithTag:DESCRIPTION_TAG];
itemDescription.text = displayableEntity.entityDesctiption;
}
}
// some code removed to make it brief
- (void)tableView:(UITableView *)tableView appearanceForCell:(MyTableViewCell *)cell withEntity:(DisplayableEntity *)entity {
// cell image view
UIImageView *cellImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[entity displayImageName]]];
[cellImageView setTag:IMAGEVIEW_TAG];
[cell addSubview:cellImageView];
// adding entity name label
UILabel *itemTitleName = [self itemTitleNameLabelWithFrame:itemNameLabelRect itemName:[entity entityName]];
[itemTitleName setTag:TITLEVIEW_TAG];
[cell addSubview:itemTitleName];
// adding 'assigned to' label right under the item name label
UILabel *itemDescriptionLabel = [self itemDescriptionLabelWithFrame:descriptionLabelFrame itemDescription:[entity entityDesctiption]];
[itemDescriptionLabel setTag:DESCRIPTION_TAG];
[cell addSubview:itemDescriptionLabel];
}
I see some troubles in tableView:cellForRowAtIndexPath: logic
It should be:
Dequeue cell
If cell cannot be dequeued - create the new one
Set all cell properties
I mean something like this:
- (MyTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"itemListTableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
} // <-- Note there is no else, we should reset properties in both cases
NSManagedObject *managedObject = [_fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [managedObject valueForKey:#"text"];
cell.imageView.image = [managedObject valueForKey:#"image"];
return cell;
}

Resources