Cell shows on top of section header - objective-c

I have an UITableView with custom cells and custom headers. When I move one cell upon editing, it pops up on to of the header view.
How can I keep the header view on top of all the cells?
The app uses storyboard, in case that makes a difference.
This is how it looks? https://www.dropbox.com/s/wg8oiar0d9oytux/iOS%20SimulatorScreenSnapz003.mov
This is my code:
[...]
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ListCell";
ListCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
int handleSection = [self sectionToHandle:indexPath.section];
switch (handleSection)
{
case PrivateLists:
{
if (tableView.isEditing && (indexPath.row == self.privateLists.count))
{
cell.textField.text = NSLocalizedString(#"Lägg till ny lista", nil);
cell.textField.enabled = NO;
cell.textField.userInteractionEnabled = NO;
cell.accessoryType = UITableViewCellAccessoryNone;
cell.editingAccessoryView.hidden = YES;
}
else
{
List *list = [self.privateLists objectAtIndex:indexPath.row];
cell.textField.text = list.name;
cell.textField.enabled = YES;
cell.textField.userInteractionEnabled =YES;
cell.backgroundColor = [UIColor clearColor];
cell.onTextEntered = ^(NSString* enteredString){
list.name = enteredString;
UpdateListService *service = [[UpdateListService alloc]initServiceWithList:list];
[service updatelistOnCompletion:
^(BOOL success){
DLog(#"Updated list");
NSIndexPath *newPath = [NSIndexPath indexPathForRow:0 inSection:indexPath.section];
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath];
[self moveListToTop:list.ListId newIndexPath:newPath];
justMovedWithoutSectionUpdate = YES;
}
onError:
^(NSError *error){
[[ActivityIndicator sharedInstance] hide];
[[ErrorHandler sharedInstance]handleError:error fromSender:self];
}];
};
}
}
break;
default:
return 0;
break;
}
return cell;
}
-(UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 22)];
UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 300, 21)];
[textLabel setFont:[[AXThemeManager sharedTheme]headerFontWithSize:15.0]];
[textLabel setTextColor:[[AXThemeManager sharedTheme]highlightColor]];
[textLabel setText:#"SECTION TITLE"];
[textLabel setBackgroundColor:[UIColor clearColor]];
UIImageView *backgroundView = [[UIImageView alloc]initWithImage:[AXThemeManager sharedTheme].tableviewSectionHeaderBackgroundImage];
[backgroundView setFrame:view.frame];
[view addSubview:backgroundView];
[view sendSubviewToBack:backgroundView];
[view addSubview:textLabel];
return view;
}
- (float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 22;
}
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 44;
}
[...]

Good news! I was able to fix/workaround your problem in two different ways (see below).
I would say this is certainly an OS bug. What you are doing causes the cell you have moved (using moveRowAtIndexPath:) to be placed above (in front of) the header cell in the z-order.
I was able to repro the problem in OS 5 and 6, with cells that did and didn't have UITextFields, and with the tableView in and out of edit mode (in your video it is in edit mode, I noticed). It also happens even if you are using standard section headers.
Paul, you say in one of your comments:
I solved it badly using a loader and "locking" the table while
preforming a reloadData
I am not sure what you mean by "using a loader and locking the table", but I did determine that calling reloadData after moveRowAtIndexPath: does fix the problem. Is that not something you want to do?
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath];
//[self.tableView reloadData];
// per reply by Umka, below, reloadSections works and is lighter than reloadData:
[self reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationNone];
If you dont want to do that, here is another solution that feels a little hacky to me, but seems to work well (iOS 5+):
__weak UITableViewCell* blockCell = cell; // so we can refer to cell in the block below without a retain loop warning.
...
cell.onTextEntered = ^(NSString* sText)
{
// move item in my model
NSIndexPath *newPath = [NSIndexPath indexPathForRow:0 inSection:indexPath.section];
[self.itemNames removeObjectAtIndex:indexPath.row];
[self.itemNames insertObject:sText atIndex:0];
// Then you can move cell to back
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath];
[self.tableView sendSubviewToBack:blockCell]; // a little hacky
// OR per #Lombax, move header to front
UIView *sectionView = [self.tableView headerViewForSection:indexPath.section];
[self.tableView bringSubviewToFront:sectionView];

It's a bug.
You can quickly solve it by adding, after the line:
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath];
this lines:
UIView *sectionView = [self.tableView headerViewForSection:indexPath.section];
[self.tableView bringSubviewToFront:sectionView];

Not a solution but your code has number of issues. Who knows what happens if you fix them ;)
(1) Your cell may be nil after this line:
ListCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
It should look like this:
ListCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[ListCell alloc] initWithStyle:style
reuseIdentifier:cellIdentifier] autorelease];
}
(2) Two memory leaks in
-(UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger)section
->>Fix (When you add the label as subview it gets +1 ref).
UILabel *textLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10, 0, 300, 21)] autorelease];
->>Fix (When you add the view as subview it gets +1 ref).
UIImageView *backgroundView = [[[UIImageView alloc]initWithImage:[AXThemeManager sharedTheme].tableviewSectionHeaderBackgroundImage] autorelease];
(3) Not a defect but this may help you. Try using this instead of [table reloadData]. It allows to animate things nicely and is not such a hardcore way to update the table. I'm sure it is much more lightweight. Alternatively try to look for other "update" methods. Given you don't delete rows in your example, something like [updateRowsFrom:idxFrom to:idxTo] would help.
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0]
withRowAnimation:UITableViewRowAnimationAutomatic];

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
float heightForHeader = 40.0;
if (scrollView.contentOffset.y<=heightForHeader&&scrollView.contentOffset.y>=0) {
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
} else if (scrollView.contentOffset.y>=heightForHeader) {
scrollView.contentInset = UIEdgeInsetsMake(-heightForHeader, 0, 0, 0);
}
}

What I did to solve this problem was to set the zPosition of the view in the section header.
headerView.layer.zPosition = 1000 //just set a bigger number, it will show on top of all other cells.

Related

iOS6 UITableView section header duplicates

I have an UITableView with expandable rows in section 4. When one row is expanded the others need to be collapsed. I reload specified rows and scroll table to have the expanded one on top. Here's the code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.section == 4)
{
if (indexPath.row == 0)
{
if (hypoExpanded)
{
hypoExpanded = NO;
[self performSelector:#selector(reloadRowWithScrollForIndexPath:) withObject:indexPath afterDelay:kAnimationDelay];
}
else
{
hypoExpanded = YES;
moodExpanded = NO;
activityExpanded = NO;
NSArray *indexArray = [NSArray arrayWithObjects:indexPath, [NSIndexPath indexPathForRow:1 inSection:4], [NSIndexPath indexPathForRow:2 inSection:4], nil];
[self performSelector:#selector(reloadRowWithScrollForIndexArray:) withObject:indexArray afterDelay:kAnimationDelay];
}
... }
}
- (void)reloadRowWithScrollForIndexArray:(NSArray *)indexArray
{
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:((NSIndexPath *)[indexArray objectAtIndex:0]).row inSection:((NSIndexPath *)[indexArray objectAtIndex:0]).section] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
- (void)reloadRowWithScrollForIndexPath:(NSIndexPath *)indexPath
{
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
switch (section)
{
case 1:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"bgc-info"]];
break;
case 2:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"in-info"]];
break;
case 3:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"bp-info"]];
break;
case 4:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"per-info"]];
break;
}
return nil;
}
Sometimes a random section header (1, 2 or 3) duplicates and overlays the cell that belongs to that section. Scrolling the table to make the section disappear doesn't help. When I scroll back the duplicated header still exists.
It only happens on iOS 6. Invoking performSelectorOnMainThread: is not helpful either. Also, without calling scrollToRowAtIndexPath: everything works fine. What could possibly cause this behaviour?
You can see a screenshot here:
I had the same problem. Check for uncommitted animation in your code
[UIView beginAnimations:nil context:NULL];
... should be committed below

UITableView scroll is choppy

Here is my cellForRowAtIndexPath method. Using ARC in my project.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString* cellIdentifier = #"ActivityCell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
Activity* activityToShow = [self.allActivities objectAtIndex:indexPath.row];
//Cell and cell text attributes
cell.textLabel.text = [activityToShow name];
//Slowing down the list scroll, I guess...
LastWeekView* lastWeekView = [[LastWeekView alloc] initWithFrame:CGRectMake(10, 39, 120, 20)];
[lastWeekView setActivity:activityToShow];
lastWeekView.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:lastWeekView];
return cell;
}
LastWeelView allocation is slowing down the scroll i guess. In the lastWeekView, I fetch relationships of an entity from CoreData, perform a calculation on those values and draw some colors inside its drawRect method.
Here is the drawRect of LastWeekView
- (void)drawRect:(CGRect)rect
{
NSArray* activityChain = self.activity.computeChain; //fetches its relationships data
for (id item in activityChain) {
if (marking == [NSNull null])
{
[notmarkedColor set];
}
else if([(NSNumber*)marking boolValue] == YES)
{
[doneColor set];
}
else if([(NSNumber*)marking boolValue] == NO)
{
[notdoneColor set];
}
rectToFill = CGRectMake(x, y, 10, 10);
CGContextFillEllipseInRect(context, rectToFill);
x = x + dx;
}
}
What can I do to smoothen the scroll of tableView? If I have to asynchronously add this lastWeekView to each cell's contentView, how can i do it? please help.
I'd suggest allocating LastWeekView in cell's allocation scope. Also - fetch all core data objects in viewDidLoad so that in cellForRowAtIndexPath: method would retrieve it from array and not from the store. It should look something like this:
- (void)viewDidLoad
...
_activities = [Activity fetchAllInContext:managedObjectContext];
...
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCell];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
LastWeekView* lastWeekView = [[LastWeekView alloc] initWithFrame:CGRectMake(10, 39, 120, 20)];
lastWeekView.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:lastWeekView];
}
Activity *activityToShow = [_activities objectAtIndex:[indexPath row]];
LastWeekView *lastWeekView = (LastWeekView *)[[[cell contentView] subviews] lastObject];
[lastWeekView setActivity:activityToShow];
return cell;
}
Note that you may also subclass the UITableViewCell to replace contentView with your LastWeekView to quickly access the activity property.

IOS custom cell with labels showing wrong text when cell reused

I have been trying to figure this out for a bit. I create a custom cell in its own xib file. In my view controller I have setup a table view controller with sections. The data that is being pulled into the table View is based off a fetch request controller from some core data that I have. I set up the custom cell in the cellForRowAtIndexPath function. I am creating a label for each cell within this function and populating the label with some data from the managed object. Everything seems ok when I first run. However, when I try to scroll up and down and new cells are reused the data in the labels are placed in the wrong cells. I have seen and heard this has to do with the reuse of cells. However, have not seen much examples on correcting this issue. Below is some of the code I have in my cellForRowAtIndexPath function. Let me know if any other input may be needed. Thanks for any help.
-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:#"CustomCell"];
/* do this to get unique value per cell due to sections. */
NSInteger indexForCell = indexPath.section * 1000 + indexPath.row + 1;
NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
NSString *lastSession = nil;
UILabel *lastSessionLabel = nil;
if(cell == nil) {
lastSession = [managedObject valueForKey:#"last_session"];
[self.tableView registerNib:[UINib nibWithNibName:#"CustomCell"
bundle:[NSBundle mainBundle]]
forCellReuseIdentifier:#"CustomCell"];
self.tableView.backgroundColor = [UIColor clearColor];
cell = [aTableView dequeueReusableCellWithIdentifier:#"CustomCell"];
lastSessionLabel = [[UILabel alloc]initWithFrame:CGRectMake(410,55, 89, 35)];
lastSessionLabel.textAlignment = UITextAlignmentLeft;
lastSessionLabel.tag = indexForCell;
lastSessionLabel.font = [UIFont systemFontOfSize:17];
lastSessionLabel.highlighted = NO;
lastSessionLabel.backgroundColor = [UIColor clearColor];
cell.contentView.tag = indexForCell;
[cell.contentView addSubview:lastSessionLabel];
} else {
lastSessionLabel = (UILabel *)[cell viewWithTag:indexForCell];
}
if (lastSession && lastSession.length) {
lastSessionLabel.text = lastSession;
}
cell.textLabel.text = [NSString stringWithFormat:#"%#%#%#%#", #"Dr. ",
[managedObject valueForKey:#"first_name"],
#" " ,
[managedObject valueForKey:#"last_name"]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.editingAccessoryType = UITableViewCellAccessoryNone;
return cell;
}
** Revised Code **
Below are the changes to code: in viewDidLoad is the following:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:#"CustomCell"
bundle:[NSBundle mainBundle]]
forCellReuseIdentifier:#"CustomCell"];
self.tableView.backgroundColor = [UIColor clearColor];
}
in -(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:#"CustomCell"];
NSInteger indexForCell = indexPath.section * 1000 + indexPath.row + 1;
NSLog(#"index for cell: %d",indexForCell);
NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
NSString *lastSession = [managedObject valueForKey:#"last_session"];
UILabel *lastSessionLabel = nil;
if(cell == nil) {
NSLog(#"Cell is nil! %#", [managedObject valueForKey:#"first_name"]);
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CustomCell"];
self.tableView.backgroundColor = [UIColor clearColor];
}
lastSessionLabel = [[UILabel alloc]initWithFrame:CGRectMake(410,55, 89, 35)];
lastSessionLabel.textAlignment = UITextAlignmentLeft;
lastSessionLabel.tag = indexForCell;
lastSessionLabel.font = [UIFont systemFontOfSize:17];
lastSessionLabel.highlighted = NO;
lastSessionLabel.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:lastSessionLabel];
/* Appropriate verbiage for nil last session. */
if (lastSession && lastSession.length) {
lastSessionLabel.text = lastSession;
}
return cell;
}
I am still having issues again with the label cell text changing when I scroll for different cells. I read some where about maybe having to use the prepareForReuse function for this.
You are only fetching lastSession when you create a new cell. Try putting this line before the if(cell == nil) statement.
lastSession = [managedObject valueForKey:#"last_session"];
I.e. this:
NSString *lastSession = [managedObject valueForKey:#"last_session"];
in stead of this:
NSString *lastSession = nil;
UPDATE
You are also setting the same tag for two views:
lastSessionLabel.tag = indexForCell;
...
cell.contentView.tag = indexForCell;
Based on your code sample you should only use the first line, i.e. set the tag for the lastSessionLabel
SECOND UPDATE
You should also only call registerNib: once in your view lifecycle, e.g. in viewDidLoad, not every time you need a new cell. Furthermore, you should create a new cell if cell == nil in stead of using dequeueReusableCellWithIdentifier:. E.g.
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CustomCell"];

How to get a UITableViewCell change its background color by tapping a UIBarButtonItem?

I'm trying to make a UIBarButtonItem in the right-corner of my tableView in order to highlight and un-highlight a cell when pressed.
In less words, when users press the button, a range of cells will change their background color from white to yellow.
I'm failing to make that though, because every time i press that button the app crashes.
Here's the code i'm using to create the button:
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *barButton;
barButton = [[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"high.png"] style:UIBarButtonItemStyleBordered target:self action:#selector(colorCells:)] autorelease];
self.navigationItem.rightBarButtonItem = barButton;
}
And here to make it highlight a range of cells:
- (void) colorCells:(id)sender
{
UITableViewCell *cell;
NSString *cellValue = cell.textLabel.text;
if ([cellValue isEqual: #"textTheCellShouldBeEqualTo"]){
cell.backgroundColor = [UIColor colorWithRed:251/255.0f green:255/255.0f blue:192/255.0f alpha:1]; ;
cell.imageView.image = [UIImage imageNamed:#"hot.png"];
}
else {
cell.imageView.image = nil;
cell.backgroundColor = [UIColor whiteColor];
}
}
Where am i failing? It's supposed to work fine. Or? Am i missing something? The view is a UITableViewController.
EDIT
I modified my code like so:
- (void) colorCells:(id)sender{
UITableViewCell *cell;
NSInteger nSections = [self.tableView numberOfSections];
for (int j=0; j<nSections; j++) {
NSInteger nRows = [self.tableView numberOfRowsInSection:j];
for (int i=0; i<nRows; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:j];
cell = [self.tableView cellForRowAtIndexPath:indexPath];
}
NSString *cellValue = cell.textLabel.text;
if ([cellValue isEqual: #"textTheCellShouldBeEqualTo"] ){
cell.backgroundColor = [UIColor colorWithRed:251/255.0f green:255/255.0f blue:192/255.0f alpha:1]; ;
cell.imageView.image = [UIImage imageNamed:#"hot.png"];
}
else {
cell.imageView.image = nil;
cell.backgroundColor = [UIColor whiteColor];
}
[self.tableView reloadData];
}
}
Now it doesn't crash, but it doesn't color the background too. Any ideas?
Basing the background color off of the text in a cell seems incredibly fragile. What determines that a cell should be highlighted? Does it change? Surely, the color of the background corresponds to a specific property of the objects in your data source. A more robust approach would be to use an NSMutableIndexSet property on your class to track a set of row indexes require highlighting upon tapping the bar button.
Consider this example. I'm assuming that rowsToHighlight is an instance of NSMutableIndexSet declared in your class and that it has been populated with the indexes of rows that require highlighting. We're going to implement -tableView:willDisplayCell:forRowAtIndexPath: to adjust the background color of the cell depending if the provided index path is a member of rowsToHighlight.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([self.rowsToHighlight containsIndex:indexPath.row])
{
cell.backgroundColor = [UIColor yellowColor];
}
}
Then in the method that is fired by your bar button, just do an empty update block to get the table to reload with animation.
- (void)colorCells:(id)sender
{
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
Your cells won't redraw unless you tell the table view which contains them to reload them. You can do this with one of several methods. You may consider [someTableView reloadData] or one of these methods.
Also, your cell object is not the one in your table view. You might consider this:
- (void) colorCells:(id)sender
{
UITableViewCell *cell;
//grab a cell
cell = [self tableView:self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:someRow inSection:someSection]];
NSString *cellValue = cell.textLabel.text;
if ([cellValue isEqual: #"textTheCellShouldBeEqualTo"]){
cell.backgroundColor = [UIColor colorWithRed:251/255.0f green:255/255.0f blue:192/255.0f alpha:1]; ;
cell.imageView.image = [UIImage imageNamed:#"hot.png"];
}
else {
cell.imageView.image = nil;
cell.backgroundColor = [UIColor whiteColor];
}
//perhaps you need to reload the table as well
[self.tableView reloadData];
}

app crashes when i try to scroll the tableview

when i try to scroll my tableview it crashes the app,below shown is my code please help me to fix this issue
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
NSLog(#"indexPath.row---%d",indexPath.row);
UILabel *skuLbl;
// *cellImgView;
static NSString *cellIdentifier=#"Cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell==nil){
NSLog(#"indexPath cell");
cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]autorelease];
UIImageView *cellImgView=[[UIImageView alloc]initWithFrame:CGRectMake(25,20,717,125)];
cellImgView.image=[UIImage imageNamed:#"cell.png"];
[cell.contentView addSubview:cellImgView];
skuLbl=[[UILabel alloc]initWithFrame:CGRectMake(62,20,680,125)];
skuLbl.backgroundColor=[UIColor clearColor];
skuLbl.font=[UIFont fontWithName:#"helvetica" size:40];
skuLbl.textColor=[UIColor blackColor];
[cell.contentView addSubview:skuLbl];
cell.selectionStyle=NO;
tableView.separatorColor=[UIColor whiteColor];
}
// NSLog(#"inside cell--%#",[[appDelegateObj.parsedRowsSku objectAtIndex:indexPath.row]objectForKey:#"SKU"]);
// skuLbl.text=[[appDelegateObj.parsedRowsSku objectAtIndex:indexPath.row]objectForKey:#"SKU"];
skuLbl.text=[NSString stringWithFormat:#"%d",indexPath.row];
return cell;
}
When you scroll your table view it tries to reuse its cells so
if(cell==nil){
...
}
may not get called and your skuLbl pointer remains not initialized. So later you're trying to access that invalid pointer and that results in crash.
You need to get reference to label outside of initialization block to make sure it is always valid:
UILabel *skuLbl = nil;
static NSString *cellIdentifier=#"Cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell==nil){
...
skuLbl.tag = 100;
...
}
skuLbl = (UILabel*)[cell.contentView viewWithTag:100];
...
make sure your number of rows are equals to the size of your array or whatever you're using with this method:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.myArray count]; }
Edit your code as below::
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
UILabel *skuLbl = nil;
static NSString *cellIdentifier=#"Cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell==nil) {
cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]autorelease];
UIImageView *cellImgView=[[UIImageView alloc]initWithFrame:CGRectMake(25,20,717,125)];
cellImgView.image=[UIImage imageNamed:#"cell.png"];
[cell.contentView addSubview:cellImgView];
skuLbl=[[UILabel alloc]initWithFrame:CGRectMake(62,20,680,125)];
skuLbl.tag = 100;
skuLbl.backgroundColor=[UIColor clearColor];
skuLbl.font=[UIFont fontWithName:#"helvetica" size:40];
skuLbl.textColor=[UIColor blackColor];
[cell.contentView addSubview:skuLbl];
cell.selectionStyle=NO;
tableView.separatorColor=[UIColor whiteColor];
} else {
// This method called at creation and scrolling of tableview for every individual cell.
// Due to creation and scrolling of tableview skuLbl refrence get nil
// So get new refrence of skuLbl from cell's contentView as below
skuLbl = (UILabel*)[cell.contentView viewWithTag:100];
}
skuLbl.text=[NSString stringWithFormat:#"%d",indexPath.row];
return cell;
}