Table View displaying different images while scrolling - objective-c

I am loading some images in my table view with a click of a button.The images are loaded fine and in desired positions.But when i scroll the table view then images seems to change .Let me elaborate only 2 rows are visible in my table view initially ,and lets assume the images are there in both rows and 4 images in a row.Now when i scroll the table view downwards or upwards the row which is scrolled above or below the table view frame will show the new image in its image view.And everytime when i scroll the images keep on changing.What could be the reason.I am scratching my head with this.Please help.I am posting a part of my code:-
-(UITableViewCell*)tableView(UITableView*)
ableViewcellForRowAtIndexPath(NSIndexPath*)indexPath {
UITableViewCell *cell = nil;
static NSString *AutoCompleteRowIdentifier = #"AutoCompleteRowIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (cell == nil) {
cell=[[[UITableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:AutoCompleteRowIdentifier] autorelease];
}
UIImageView * imageView1 = [[[UIImageView alloc] initWithFrame:CGRectMake(25, 4, 80, 80)] autorelease];
UIImageView * imageView2 = [[[UIImageView alloc] initWithFrame:CGRectMake(115,4,80, 80)] autorelease];
UIImageView * imageView3 = [[[UIImageView alloc] initWithFrame:CGRectMake(205,4, 80, 80)] autorelease];
UIImageView * imageView4 = [[[UIImageView alloc] initWithFrame:CGRectMake(295,4, 80, 80)] autorelease];
imageView1.tag = 1;
imageView2.tag = 2;
imageView3.tag = 3;
imageView4.tag = 4;
[cell.contentView addSubview:imageView1];
[cell.contentView addSubview:imageView2];
[cell.contentView addSubview:imageView3];
[cell.contentView addSubview:imageView4];
UIImageView * imageView;
for ( int i = 1; i <= 4; i++ ) {
imageView = (UIImageView *)[cell.contentView viewWithTag:i];
imageView.image = nil;
}
int photosInRow;
if ( (indexPath.row < [tableView numberOfRowsInSection:indexPath.section] - 1) ||
(count % 4 == 0) ) {
photosInRow = 4;
} else {
photosInRow = count % 4;
}
for ( int i = 1; i <= photosInRow; i++ ) {
imageView = (UIImageView *)[cell.contentView viewWithTag:i];
[self setImage1:imageView];
}
return cell;
}
-(void)setImage1:(UIImageView *)imageView
{
UIImageView *imageView1=[[UIImageView alloc]init];
imageView1=imageView;
imageView1.image = [UIImage imageNamed:[NSString stringWithFormat:#"%d.png", j]];
j++;
}
Any help will be appreciated.
Thanks,
Christy

Your setImage1: method should be modified to take in the photo index as j is not a proper way to track the current image as cellForRowAtIndexPath: may be called in any order.
- (void)setImage1:(UIImageView *)imageView forPhotoIndex:(NSInteger)index {
imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%ld.png", index]];
}
and minor modification in cellForRowAtIndexPath: would be,
[..]
for ( int i = 1; i <= photosInRow; i++ ) {
imageView = (UIImageView *)[cell.contentView viewWithTag:i];
[self setImage1:imageView forPhotoIndex:(indexPath.row * 4 + i - 1)];
}
[..]

When reusing a cell, you currently just add new UImageView instances. The reused cell already has subviews added and you just add more. Be sure to only add new UIImageViews if the cell was not reused before (within the if-clause)
if (cell == nil) {
cell=[[[UITableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:AutoCompleteRowIdentifier] autorelease];
UIImageView * imageView1 = [[[UIImageView alloc] initWithFrame:CGRectMake(25, 4, 80, 80)] autorelease];
UIImageView * imageView2 = [[[UIImageView alloc] initWithFrame:CGRectMake(115,4,80, 80)] autorelease];
UIImageView * imageView3 = [[[UIImageView alloc] initWithFrame:CGRectMake(205,4, 80, 80)] autorelease];
UIImageView * imageView4 = [[[UIImageView alloc] initWithFrame:CGRectMake(295,4, 80, 80)] autorelease];
imageView1.tag = 1;
imageView2.tag = 2;
imageView3.tag = 3;
imageView4.tag = 4;
[cell.contentView addSubview:imageView1];
[cell.contentView addSubview:imageView2];
[cell.contentView addSubview:imageView3];
[cell.contentView addSubview:imageView4];
}
EDIT: See comments below about issues in setting the actual image.

Related

UIImage with UITapGestureRecognizer in first row of UITableViewController not working properly

I've got a UITableViewController subclass that is subclassed by two other classes. In some of the cells of both tables I have an image that the user can click on to perform an action. It all works and I'm happy except that in one of the 2 subclasses the first row of that table has an issue. You can only click the image by clicking to the rightmost edge of the image. If you click in the body of the image it calls the table's didSelectRowAtIndexPath instead.
What boggles me is that it works in the other class for all rows and even in the one it doesn't work for it works in all the other rows where that image shows up. Here's the code I'm using to add the image and gesture recognizer into my cell:
UIImageView *imgparent = [[UIImageView alloc] initWithFrame:CGRectMake(offsetleftmain, 24.0, 14.0, 16.0)];
imgparent.image = [UIImage imageNamed:#"item_open.png"];
imgparent.tag = ITEMOPENTAG;
// add listener
imgparent.userInteractionEnabled = YES;
UITapGestureRecognizer *singleFingerDTapParent = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(loadChildren:)];
[imgparent addGestureRecognizer:singleFingerDTapParent];
[singleFingerDTapParent release];
[cell.contentView addSubview:imgparent];
[imgparent release];
I'm testing in the simulator by the way. I've tried replacing the image with a button but still the problem persists. Any ideas?
EDIT: Here's the beginnings of the code that is called when the image is clicked. Again, this works but in the case of that one row it only works if you click on the right edge of the image. I've attached a screenshot to illustrate. The first circle indicates where I have to tap in order to get my gesture to be called. The second shows an example in the very same table that allows you to click the entire image. I'm confounded.
- (void)loadChildren:(UIGestureRecognizer *)gestureRecognizer {
NSLog(#"loadChildren");
// get the cell
UITableViewCell *cell = (UITableViewCell *)gestureRecognizer.view.superview.superview;
UIImageView *imgvw = (UIImageView *)[cell viewWithTag:ITEMOPENTAG]; // open arrow
[imgvw setHidden:YES]; // hide open arrow
imgvw = (UIImageView *)[cell viewWithTag:ITEMCLOSETAG]; // close arrow
[imgvw setHidden:NO]; // show close arrow
// get the record for the cell
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
}
EDIT: Here's the complete tableView:cellForRowAtIndexPath:indexPath. Keep in mind that it's being called from the cellForRowAtIndexPath of 2 other subclasses of this class, each simply passing in an identifier withType:
- (UITableViewCell *)tableView:(UITableView *)tv
cellForRowAtIndexPath:(NSIndexPath *)indexPath
withType:(NSString *)s_type
{
UITableViewCell *cell = nil;
// if dealing with empty region then show no tasks cell
if(s_type == #"noTasksCell"){
cell = [tv dequeueReusableCellWithIdentifier:#"noTasksCell"];
if( cell == nil ) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"noTasksCell"] autorelease];
}
cell.textLabel.text = #"No tasks";
cell.textLabel.textColor = [UIColor lightGrayColor];
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
UILabel *lblMain;
NSDictionary *o_rec = [self getRecForPath:indexPath];
NSString *s_cell = #"rowCell";
BOOL b_parent = NO;
BOOL b_parentOpen = NO;
BOOL b_child = NO;
BOOL b_checked = NO;
if([self isParent:indexPath]){
b_parent = YES;
b_parentOpen = !([o_rec objectForKey:#"b_open"] == nil || [[o_rec objectForKey:#"b_open"] isEqualToNumber:[NSNumber numberWithInt:0]]);
s_cell = [s_cell stringByAppendingString:#"Parent"];
}
if([o_rec objectForKey:#"b_child"] != nil){
b_child = YES;
s_cell = [s_cell stringByAppendingString:[NSString stringWithFormat:#"Child%#",[o_rec objectForKey:#"indent"]]];
}
if([[o_rec objectForKey:#"checked"] isEqualToNumber:[NSNumber numberWithInt:1]]){
b_checked = YES;
s_cell = [s_cell stringByAppendingString:#"isComplete"];
}
// add the following to the name:
// - project id
// - width of table to the name so that rotations will change the cell dequeue names
// - priority
s_cell = [s_cell stringByAppendingFormat:
#"Proj%#Width%dP%#"
,[o_rec objectForKey:#"project_id"]
,(int)tv.bounds.size.width
,[[o_rec objectForKey:#"priority"] stringValue]
];
cell = [tv dequeueReusableCellWithIdentifier:s_cell];
if( cell == nil ) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:s_cell] autorelease];
cell.textLabel.hidden = YES; // hide the regular text label
cell.selectedBackgroundView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
cell.selectedBackgroundView.backgroundColor = [delegate colorForHexWithAlpha:0xffcc66ff];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
int offsetleftmain = 10;
if(b_child){
offsetleftmain += ([[o_rec objectForKey:#"indent"] intValue]-1) * 18;
}
if(b_parent){
// parent arrow
UIImageView *imgparent = [[UIImageView alloc] initWithFrame:CGRectMake(offsetleftmain, 24.0, 14.0, 16.0)];
imgparent.image = [UIImage imageNamed:#"item_open.png"];
imgparent.tag = ITEMOPENTAG;
// add listener
imgparent.userInteractionEnabled = YES;
UITapGestureRecognizer *singleFingerDTapParent = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(loadChildren:)];
singleFingerDTapParent.numberOfTapsRequired = 1;
singleFingerDTapParent.numberOfTouchesRequired = 1;
[imgparent addGestureRecognizer:singleFingerDTapParent];
[singleFingerDTapParent release];
[cell.contentView addSubview:imgparent];
[imgparent release];
// close arrow
UIImageView *imgparent2 = [[UIImageView alloc] initWithFrame:CGRectMake(offsetleftmain-2, 24.0, 16.0, 14.0)];
imgparent2.image = [UIImage imageNamed:#"item_close.png"];
imgparent2.tag = ITEMCLOSETAG;
imgparent2.userInteractionEnabled = YES;
UITapGestureRecognizer *singleFingerDTapParent2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(hideChildren:)];
[imgparent2 addGestureRecognizer:singleFingerDTapParent2];
[singleFingerDTapParent2 release];
[cell.contentView addSubview:imgparent2];
[imgparent2 release];
}
offsetleftmain += 18;
// checkbox
UIImageView *imgchk = [[UIImageView alloc] initWithFrame:CGRectMake(offsetleftmain, 20.0, 24.0, 24.0)];
imgchk.image = [UIImage imageNamed:#"check_empty.png"];
imgchk.tag = EMPTYCHECKTAG;
// add listener
imgchk.userInteractionEnabled = YES;
UITapGestureRecognizer *singleFingerDTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(checkOnItem:)];
[imgchk addGestureRecognizer:singleFingerDTap];
[singleFingerDTap release];
[cell.contentView addSubview:imgchk];
[imgchk release];
// checked checkbox
UIImageView *imgchk2 = [[UIImageView alloc] initWithFrame:CGRectMake(offsetleftmain, 20.0, 24.0, 24.0)];
imgchk2.image = [UIImage imageNamed:#"check_checked.png"];
imgchk2.tag = CHECKTAG;
// add listener
imgchk2.userInteractionEnabled = YES;
UITapGestureRecognizer *singleFingerDTap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(checkOffItem:)];
[imgchk2 addGestureRecognizer:singleFingerDTap2];
[singleFingerDTap2 release];
[cell.contentView addSubview:imgchk2];
[imgchk2 release];
offsetleftmain += 28;
// main label
lblMain = [[UILabel alloc] initWithFrame:CGRectMake(offsetleftmain, 22.0, tv.bounds.size.width-offsetleftmain-10, 30.0)];
lblMain.tag = MAINLABELTAG;
lblMain.numberOfLines = 4;
lblMain.font = delegate.font_dflt;
// change color based on priority
if (5-[[o_rec objectForKey:#"priority"] intValue] == 1)
lblMain.textColor = [UIColor redColor];
else if (5-[[o_rec objectForKey:#"priority"] intValue] == 2)
lblMain.textColor = [delegate colorForHexWithAlpha:H_P2COLOR];
else if (5-[[o_rec objectForKey:#"priority"] intValue] == 3)
lblMain.textColor = [delegate colorForHexWithAlpha:H_P3COLOR];
[cell.contentView addSubview:lblMain];
[lblMain release];
// show action sheet for long press and hold
UILongPressGestureRecognizer *clicknHold = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(cellClicknHold:)];
[cell addGestureRecognizer:clicknHold];
[clicknHold release];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// task text
lblMain = (UILabel *)[cell viewWithTag:MAINLABELTAG];
lblMain.text = [self formatContent:[o_rec objectForKey:#"content"]];
CGRect newFrame = lblMain.frame;
newFrame.size.height = [[o_rec objectForKey:#"height"] floatValue];
//newFrame.size.height = [[o_rec objectForKey:#"height"] floatValue]+12;
lblMain.frame = newFrame;
// set checked status
[(UIImageView *)[cell viewWithTag:EMPTYCHECKTAG]
setHidden:[[o_rec objectForKey:#"checked"] boolValue]];
[(UIImageView *)[cell viewWithTag:CHECKTAG]
setHidden:![[o_rec objectForKey:#"checked"] boolValue]];
// show open arrow if dealing with parent cell
if (b_parent) {
//NSLog(#"b_parentOpen:%d",b_parentOpen);
[(UIImageView *)[cell viewWithTag:ITEMOPENTAG] setHidden:b_parentOpen];
[(UIImageView *)[cell viewWithTag:ITEMCLOSETAG] setHidden:!b_parentOpen];
}
return cell;
}
Just in case someone runs into a similar issue as rare as that may be maybe this will help avoid someone going bald pulling their hair out. So my problem wasn't with the tableView itself but a sidebar I have that is similar to the facebook sidebar that slides in and out. My sidebar has a tableview in it and that table has a header on it that for some reason when it was right beside my other table was somehow preventing clicks to the image in that first row. My solution was simply to position that sidebar view a little bit further offscreen away from the view it was beside instead of being right next to it. Problem solved. Thanks to all who tried to help me out.

image getting overlaped in table view cell

I m parsing a json feed and populating my table view.if my parsed value is "1" and if its for the first four rows of table view cell.i got to make a green checkmark and if its not for the first four rows the checkmark got to be grey check.if my parsed value is null.i got to make no checkmark.everthng works fine.but if i scroll my table view .the check mark images gets overlaped.below is the screen shot and the code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//[tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *boy=[self.media1 objectAtIndex:indexPath.row];
NSString *str=[[NSString alloc]initWithFormat:#"%#",boy];
if ([str isEqualToString:#"1"])
{
if(indexPath.row==0||indexPath.row==1||indexPath.row==2||indexPath.row==3)
{
CGRect starFrame = CGRectMake(260, 18, 50, 40);
UIImageView *starImage = [[[UIImageView alloc] initWithFrame:starFrame] autorelease];
starImage.image = [UIImage imageNamed:#"tic.png"];
[cell.contentView addSubview:starImage];
}
else
{
CGRect starFrame1 = CGRectMake(260, 18, 50, 40);
UIImageView *starImage1 = [[[UIImageView alloc] initWithFrame:starFrame1] autorelease];
starImage1.image = [UIImage imageNamed:#"brrr.png"];
[cell.contentView addSubview:starImage1];
}
}
cell.textLabel.text=[story objectAtIndex:indexPath.row];
return cell;
}
You are reusing the cell. So, tableView will return used cell once they are not visible.
To avoid this problem, you should right below code.
if ([str isEqualToString:#"1"])
{
if(indexPath.row==0||indexPath.row==1||indexPath.row==2||indexPath.row==3)
{
CGRect starFrame = CGRectMake(260, 18, 50, 40);
UIImageView *starImage = [[[UIImageView alloc] initWithFrame:starFrame] autorelease];
starImage.image = [UIImage imageNamed:#"tic.png"];
starImage.tag = 1000;
[cell.contentView addSubview:starImage];
}
else
{
CGRect starFrame1 = CGRectMake(260, 18, 50, 40);
UIImageView *starImage1 = [[[UIImageView alloc] initWithFrame:starFrame1] autorelease];
starImage1.image = [UIImage imageNamed:#"brrr.png"];
starImage.tag = 1000;
[cell.contentView addSubview:starImage1];
}
}
else
{
UIImageView *starImage1 = [cell.contentView viewWithTag:1000];
starImage1.image = nil;
}
Use the following code,
if ([str isEqualToString:#"1"])
{
if(indexPath.row==0||indexPath.row==1||indexPath.row==2||indexPath.row==3)
{
CGRect starFrame = CGRectMake(260, 18, 50, 40);
UIImageView *starImage = [[[UIImageView alloc] initWithFrame:starFrame] autorelease];
starImage.image = [UIImage imageNamed:#"tic.png"];
starImage.tag = 1000;
[cell.contentView addSubview:starImage];
}
else
{
CGRect starFrame1 = CGRectMake(260, 18, 50, 40);
UIImageView *starImage1 = [[[UIImageView alloc] initWithFrame:starFrame1] autorelease];
starImage1.image = [UIImage imageNamed:#"brrr.png"];
starImage1.tag = 1000;
[cell.contentView addSubview:starImage1];
}
}
else
{
UIImageView *starImage = [cell.contentView viewWithTag:1000];
if (starImage) {
[starImage removeFromSuperview];
}
}

Adding imageViews to next row of table view

in my app i have a table view and i am adding 4 image view to the first row of my table view .Now i want to add the image view to the next row.How can i do that in the existing code please help.I am posting my part of code:--
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *AutoCompleteRowIdentifier = #"AutoCompleteRowIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier] autorelease];
UIImageView * imageView1 = [[[UIImageView alloc] initWithFrame:CGRectMake(25, 4, 80, 80)] autorelease];
UIImageView * imageView2 = [[[UIImageView alloc] initWithFrame:CGRectMake(115,4,80, 80)] autorelease];
UIImageView * imageView3 = [[[UIImageView alloc] initWithFrame:CGRectMake(205,4, 80, 80)] autorelease];
UIImageView * imageView4 = [[[UIImageView alloc] initWithFrame:CGRectMake(295,4, 80, 80)] autorelease];
UIImageView * imageView5 = [[[UIImageView alloc] initWithFrame:CGRectMake(25, 4, 80, 80)] autorelease];
UIImageView * imageView6 = [[[UIImageView alloc] initWithFrame:CGRectMake(115,4,80, 80)] autorelease];
int j=0;
imageView1.tag = j;
imageView2.tag = j+1;
imageView3.tag = j+2;
imageView4.tag = j+3;
imageView5.tag = j+4;
imageView6.tag = j+5;
[cell.contentView addSubview:imageView1];
[cell.contentView addSubview:imageView2];
[cell.contentView addSubview:imageView3];
[cell.contentView addSubview:imageView4];
[cell.contentView addSubview:imageView5];
[cell.contentView addSubview:imageView6];
}
for ( int i = 1; i <= j; i++ ) {
imageView = (UIImageView *)[cell.contentView viewWithTag:i];
imageView.image = nil;
}
int photosInRow;
if ( (indexPath.row < [tableView numberOfRowsInSection:indexPath.section] - 1) || ([sentence count] % 4 == 0) ) {
photosInRow = 4;
} else {
photosInRow = [sentence count] % 4;
}
for ( int i = 1; i <=[sentence count]; i++ ){
imageView = (UIImageView *)[cell.contentView viewWithTag:i];
[self setImage1:imageView];
}
return cell;
}
I want mu imageView 5 and 6 to be in next row.Please help.How to do it?i am ramming my head against the wall looking for this.
Thanks,
Christy
you can try some thing like bellow ... you basically check the present row number then build your required logic ...
UITableViewCell *cell = nil;
static NSString *AutoCompleteRowIdentifier = #"AutoCompleteRowIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier] autorelease];
}
int j=0; imageView1.tag = j;
if(0 == [indexPath row])
{
UIImageView * imageView1 = [[[UIImageView alloc] initWithFrame:CGRectMake(25, 4, 80, 80)] autorelease];
UIImageView * imageView2 = [[[UIImageView alloc] initWithFrame:CGRectMake(115,4,80, 80)] autorelease];
UIImageView * imageView3 = [[[UIImageView alloc] initWithFrame:CGRectMake(205,4, 80, 80)] autorelease];
UIImageView * imageView4 = [[[UIImageView alloc] initWithFrame:CGRectMake(295,4, 80, 80)] autorelease];
imageView2.tag = j+1;
imageView3.tag = j+2;
imageView4.tag = j+3;
[cell.contentView addSubview:imageView1];
[cell.contentView addSubview:imageView2];
[cell.contentView addSubview:imageView3];
[cell.contentView addSubview:imageView4];
}else if(0 == [indexPath row])
{
UIImageView * imageView5 = [[[UIImageView alloc] initWithFrame:CGRectMake(25, 4, 80, 80)] autorelease];
UIImageView * imageView6 = [[[UIImageView alloc] initWithFrame:CGRectMake(115,4,80, 80)] autorelease];
imageView5.tag = j+1;
imageView6.tag = j+2;
[cell.contentView addSubview: imageView5];
[cell.contentView addSubview:imageView6];
}
for ( int i = 1; i <= j; i++ ) {
imageView = (UIImageView *)[cell.contentView viewWithTag:i];
imageView.image = nil;
}

Reloading table view in xcode

I have a text box in my app with a button and a table view.Inside this table view i am creating image views which will display some images.Now when i enter a number say 5 in the text box and then click the button then 5 images are displayed on the table view out of which 4 images are in the first row .Now the problem comes if i enter number less than 5 say 3 then i have to get only 3 images in the table view but still i am getting 5 images and if i enter more than 5 then i am getting the desired number on the table view.My piece of code is:-
if([imageArray count] >0)
{
[imageArray removeAllObjects];
}
int j = [text.text intValue];
for(int i=0;i<j;i++)
{
[imageArray addObject:[UIImage imageNamed:[NSString stringWithFormat:#"%d.png", i]]];
}
[tableView reloadData];
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
if(indexPath.row == 0)
{
UIImageView *imageView1 = [[UIImageView alloc] initWithFrame:CGRectMake(0,5,100,125)];
if([imageArray count]>0)
{
imageView1.image=[UIImage imageNamed:#"CARRY.png"];
imageView1.image = [imageArray objectAtIndex:0];
[cell.contentView addSubview:imageView1];
[imageView1 release];
}
if([imageArray count]>1)
{
UIImageView *imageView2 = [[UIImageView alloc] initWithFrame:CGRectMake(150,5,100,125)];
imageView2.image = [imageArray objectAtIndex:1];
[imageView2 addSubview:button6];
[cell.contentView addSubview:imageView2];
[imageView2 release];
}
if([imageArray count]>2)
{
UIImageView *imageView3 = [[UIImageView alloc] initWithFrame:CGRectMake(310, 5, 100, 125)];
imageView3.image = [imageArray objectAtIndex:2];
[cell.contentView addSubview:imageView3];
[imageView3 release];
}
if([imageArray count]>3)
{
UIImageView *imageView4 = [[UIImageView alloc] initWithFrame:CGRectMake(460,5,100,125)];
imageView4.image = [imageArray objectAtIndex:3];
[cell.contentView addSubview:imageView4];
[imageView4 release];
}
}
else if(indexPath.row == 1)
{
if([imageArray count]>4)
{
UIImageView *imageView5 = [[UIImageView alloc] initWithFrame:CGRectMake(0,5,100,125)];
imageView5.image = [imageArray objectAtIndex:4];
[cell.contentView addSubview:imageView5];
[imageView5 release];
}
if([imageArray count]>5)
{
UIImageView *imageView6 = [[UIImageView alloc] initWithFrame:CGRectMake(150,5,100,125)];
imageView6.image = [imageArray objectAtIndex:5];
[cell.contentView addSubview:imageView6];
[imageView6 release];
}
if([imageArray count]>6)
{
UIImageView *imageView7= [[UIImageView alloc] initWithFrame:CGRectMake(310, 5, 100, 125)];
imageView7.image = [imageArray objectAtIndex:6];
[cell.contentView addSubview:imageView7];
[imageView7 release];
}
if([imageArray count]>7)
{
UIImageView *imageView8 = [[UIImageView alloc] initWithFrame:CGRectMake(460,5,100,125)];
imageView8.image = [imageArray objectAtIndex:7];
[cell.contentView addSubview:imageView8];
[imageView8 release];
}
}
else if(indexPath.row == 2)
{
if([imageArray count]>8)
{
UIImageView *imageView8 = [[UIImageView alloc] initWithFrame:CGRectMake(0,5,100,125)];
imageView8.image = [imageArray objectAtIndex:8];
[cell.contentView addSubview:imageView8];
[imageView8 release];
}
if([imageArray count]>9)
{
UIImageView *imageView8 = [[UIImageView alloc] initWithFrame:CGRectMake(150,5,100,125)];
imageView8.image = [imageArray objectAtIndex:9];
[cell.contentView addSubview:imageView8];
[imageView8 release];
}
}
return cell;
}
I am clearing the array and again adding images to it then reloading the table view but why is the output then not coming according to the needs.Please help.
Thanks,
Christy
The problem is that you're adding the image views but you aren't removing the image views that you've added earlier in case of cell reuse.

App crashing when scrolling table view

In my app i have a table view displaying images view ,,4 image view in one row .My issue is that after loading the table view with some data then if i try to scroll the table view then my app is crashing.On using the breakpoint i found that cell for row at index path methid is called again and my array tries to reload data again.Please help as its getting on my head now,i am posting my code here:--
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *AutoCompleteRowIdentifier = #"AutoCompleteRowIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier] autorelease];
UIImageView * imageView1 = [[[UIImageView alloc] initWithFrame:CGRectMake(25, 4, 70, 80)] autorelease];
UIImageView * imageView2 = [[[UIImageView alloc] initWithFrame:CGRectMake(115,4,70, 80)] autorelease];
UIImageView * imageView3 = [[[UIImageView alloc] initWithFrame:CGRectMake(205,4, 70, 80)] autorelease];
UIImageView * imageView4 = [[[UIImageView alloc] initWithFrame:CGRectMake(295,4, 70, 80)] autorelease];
UIImageView * imageView5 = [[[UIImageView alloc] initWithFrame:CGRectMake(25, 4, 70, 80)] autorelease];
UIImageView * imageView6 = [[[UIImageView alloc] initWithFrame:CGRectMake(115,4,70, 80)] autorelease];
UIImageView * imageView7 = [[[UIImageView alloc] initWithFrame:CGRectMake(205,4, 70, 80)] autorelease];
UIImageView * imageView8 = [[[UIImageView alloc] initWithFrame:CGRectMake(295,4, 70, 80)] autorelease];
UIImageView * imageView9 = [[[UIImageView alloc] initWithFrame:CGRectMake(25, 4, 70, 80)] autorelease];
UIImageView * imageView10 = [[[UIImageView alloc] initWithFrame:CGRectMake(115,4,70, 80)] autorelease];
UIImageView * imageView11 = [[[UIImageView alloc] initWithFrame:CGRectMake(205,4, 70, 80)] autorelease];
UIImageView * imageView12 = [[[UIImageView alloc] initWithFrame:CGRectMake(295,4, 70, 80)] autorelease];
imageView1.tag=1;
imageView2.tag=2;
imageView3.tag=3;
imageView4.tag=4;
imageView5.tag=5;
imageView6.tag=6;
imageView7.tag=7;
imageView8.tag=8;
imageView9.tag=9;
imageView10.tag=10;
imageView11.tag=11;
imageView12.tag=12;
if ([sentence count]>0) {
[imageViewArray insertObject:imageView1 atIndex:0];
[cell.contentView addSubview:imageView1];
}
if ([sentence count]>1) {
[imageViewArray insertObject:imageView2 atIndex:1];
[cell.contentView addSubview:imageView2];
}
if ([sentence count]>2) {
[imageViewArray insertObject:imageView3 atIndex:2];
[cell.contentView addSubview:imageView3];
}
if ([sentence count]>3) {
[imageViewArray insertObject:imageView4 atIndex:3];
[cell.contentView addSubview:imageView4];
}
if ([sentence count]>4) {
[imageViewArray insertObject:imageView5 atIndex:4];
[cell.contentView addSubview:imageView5];
}
if ([sentence count]>5) {
[imageViewArray insertObject:imageView6 atIndex:5];
[cell.contentView addSubview:imageView6];
}
if ([sentence count]>6) {
[imageViewArray insertObject:imageView7 atIndex:6];
[cell.contentView addSubview:imageView7];
}
if ([sentence count]>7) {
[imageViewArray insertObject:imageView8 atIndex:7];
[cell.contentView addSubview:imageView8];
}
if ([sentence count]>8) {
[imageViewArray insertObject:imageView9 atIndex:8];
[cell.contentView addSubview:imageView9];
}
if ([sentence count]>9) {
[imageViewArray insertObject:imageView10 atIndex:9];
[cell.contentView addSubview:imageView10];
}
if ([sentence count]>10) {
[imageViewArray insertObject:imageView11 atIndex:10];
[cell.contentView addSubview:imageView11];
}
if ([sentence count]>11 || ([sentence count]==12)) {
[imageViewArray insertObject:imageView12 atIndex:11];
[cell.contentView addSubview:imageView12];
}
}
if ([sentence count]!=0)
{
int photosInRow;
if ( (indexPath.row <
[tableView numberOfRowsInSection:indexPath.section] - 1) || ([sentence count] % 4 == 0) ) {
photosInRow = 4;
} else {
photosInRow = [sentence count] % 4;
}
for ( int i = 1; i <=photosInRow ; i++ ){
imageView = (UIImageView *)[cell.contentView viewWithTag:j];
[self setImage1:imageView];
}
}
return cell;
}
I believe the biggest problem here is the memory leaks for you imageViews. Each cell creates 12 imageViews, none of which is released. It seems that you should only create the imageViews you need (for speed), and release them correctly (for memory management).
One way to begin to rewrite this code, is the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *AutoCompleteRowIdentifier = #"AutoCompleteRowIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier] autorelease];
for (int i=0; i <= [sentence count]; ++i) {
UIImageView * imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(25+90*(i%4), 4, 70, 80)] autorelease];
imageView.tag = i+1;
[cell.contentView addSubview:imageView];
[imageView release];
}
}
return cell;
}
I don't understand why you are setting imageViewArray or imageView1 repeatedly. Also, this line:
imageView = (UIImageView *)[cell.contentView viewWithTag:j];
makes no sense as j is not defined.
On using the breakpoint i found that cell for row at index path methid is called again and my array tries to reload data again.
That's right. If you don't understand that, you don't understand how a table view works. The cells are created on demand and reused; the same cell might be reused again and again for different rows of the table as the user scrolls. That means that you must prepare all the data beforehand, and simply fetch it on demand for any section/row requested.
To put it another way, MVC: model-view-controller. Your model is your data. tableView:cellForRowAtIndexPath: is view; you must not modify the model during this, because when and how often it is called depends entirely on the needs of the view.
Another thing is that you should not be making a separate array of image views. An image view is view. If you want to store a list of something, store a list of the names of the images or something.