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];
}
}
Related
I want to create a UITableViewCell with an image between the content and the accessory view, sonly if certain condition is met.
So I have to create a custom content view with two UILabel and UIImageView as described in "Table View Programming Guide for iOS".
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UILabel *mainLabel;
UILabel *secondLabel;
UIImageView *icon;
YOEvento *aux = [[self.eventosListsContainer objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// 1. Check if it is a favourtite to display the icon
if (aux.isFavourite) {
// Evento is favourite
// 1. Create the main label view
mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(20, 8, 248, 14)] autorelease];
mainLabel.tag = MAINLABEL_TAG;
mainLabel.font = [UIFont systemFontOfSize:13.0];
mainLabel.textColor = [UIColor darkGrayColor];
mainLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:mainLabel];
// Create the date label
secondLabel = [[[UILabel alloc] initWithFrame:CGRectMake(23, 24, 245, 11)] autorelease];
secondLabel.tag = SECONDLABEL_TAG;
secondLabel.font = [UIFont systemFontOfSize:11.0];
secondLabel.textColor = [UIColor lightGrayColor];
secondLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:secondLabel];
// Create the image
icon = [[[UIImageView alloc] initWithFrame:CGRectMake(268, 12, 24, 21)] autorelease];
icon.tag = ICON_TAG;
icon.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:icon];
} else {
// Evento is not favourite
// 1. Create the main label view
mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(20, 8, 282, 14)] autorelease];
mainLabel.tag = MAINLABEL_TAG;
mainLabel.font = [UIFont systemFontOfSize:13.0];
mainLabel.textColor = [UIColor darkGrayColor];
mainLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:mainLabel];
// Create the date label
secondLabel = [[[UILabel alloc] initWithFrame:CGRectMake(23, 24, 279, 11)] autorelease];
secondLabel.tag = SECONDLABEL_TAG;
secondLabel.font = [UIFont systemFontOfSize:11.0];
secondLabel.textColor = [UIColor lightGrayColor];
secondLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:secondLabel];
}
} else {
//
if (aux.isFavourite) {
mainLabel = (UILabel *)[cell.contentView viewWithTag:MAINLABEL_TAG];
secondLabel = (UILabel *)[cell.contentView viewWithTag:SECONDLABEL_TAG];
icon = (UIImageView *)[cell.contentView viewWithTag:ICON_TAG];
} else {
mainLabel = (UILabel *)[cell.contentView viewWithTag:MAINLABEL_TAG];
secondLabel = (UILabel *)[cell.contentView viewWithTag:SECONDLABEL_TAG];
}
}
// Load cell values
if (aux.isFavourite) {
mainLabel.text = aux.nombre;
secondLabel.text = #"16 de Octubre"; // ?????????????
icon.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"29-heart"
ofType:#"png"]];
} else {
mainLabel.text = aux.nombre;
secondLabel.text = #"16 de Octubre"; // ?????????????
}
return cell;
}
The problem is that the icon image is loaded randomly because it keeps showing when reusing cells.
I have to admit that I don't fully understand the reusing cells theory.
In my original implementation (using the imageView property) it was easy, I just check is the event was not a favorite to set cell.imageView = nil. But have no idea how to do with custom contentView.
Once you create your cell, you are wanting to re-arrange its contents - this is adding unnecessary complexity. Instead you should create two different cell types - one for a favourite and one for a non-favourite. Try something like this:
static NSString *CellIdentifierFavourite = #"CellFavourite";
static NSString *CellIdentifierNonFavourite = #"CellNonFavourite";
// Other setup goes here
YOEvento *aux = [[self.eventosListsContainer objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
if (aux.isFavourite) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierFavourite];
if (cell == nil) {
// Create favourite cell here
}
// Populate favourite cell here
} else {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierNonFavourite];
if (cell == nil) {
// Create non-favourite cell here
}
// Populate non-favourite cell here
}
// Rest of method goes below
ok, so this is pretty simple one, but i hope i could explain this clearly - i have a table view that i would like to inset into a container, and then have the table bounces when it reaches the top / bottom. So far, I was able to put my table in a container, but the container is fixed on the view, while the table inside the container bounces. Again, I am looking for a way to fix the table to the container, while having the container bouncing.
Here is what I was able to do, following the code:
What I want to accomplish is to have the black box bouncing rather than the table within it.
my ViewDidLoad in the view controller .m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//General View Setup
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"backgroundimage.png"]];
self.view.backgroundColor = background;
//Table View Data
listOfItems = [[NSMutableArray alloc] init];
NSArray *appleComputers = [NSArray arrayWithObjects:#"iPhone",#"iPod",#"MacBook",#"MacBook Pro",nil];
NSDictionary *appleComputersDict = [NSDictionary dictionaryWithObject:appleComputers forKey:#"Computers"];
NSArray *otherComputers = [NSArray arrayWithObjects:#"HP", #"Dell", #"Windows", #"Sony", #"Ivory", #"IBM", nil];
NSDictionary *otherComputersDict = [NSDictionary dictionaryWithObject:otherComputers forKey:#"Computers"];
[listOfItems addObject:appleComputersDict];
[listOfItems addObject:otherComputersDict];
self.navigationItem.title = #"Computers";
// Create a table
tblSimpleTable.delegate = self;
CGRect cgRct = CGRectMake(10, 50, 300, 300);
tblSimpleTable = [[UITableView alloc] initWithFrame:cgRct style:UITableViewStyleGrouped]; // Initilize the table
[tblSimpleTable setBackgroundColor:[UIColor blackColor]];
tblSimpleTable.sectionHeaderHeight = 30.0;
tblSimpleTable.sectionFooterHeight = 30.0;
tblSimpleTable.delegate = self;
tblSimpleTable.dataSource = self;
[self.view addSubview:tblSimpleTable];
//Create the header
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 60)];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, 300, 40)];
headerLabel.text = NSLocalizedString(#"Header for the table", #"");
headerLabel.textColor = [UIColor whiteColor];
headerLabel.shadowColor = [UIColor yellowColor];
headerLabel.shadowOffset = CGSizeMake(0, 1);
headerLabel.font = [UIFont boldSystemFontOfSize:22];
headerLabel.backgroundColor = [UIColor clearColor];
[containerView addSubview:headerLabel];
self.tblSimpleTable.tableHeaderView = containerView;
}
why don’t you use UIScrollView for that.
I had tested your code & done required changes. Hope you like it.
Code :
(this is your .h file)
#import <UIKit/UIKit.h>
#interface tableScrollViewController : UIViewController
<UITableViewDelegate,UITableViewDataSource, UIScrollViewDelegate> {
UITableView *tblSimpleTable;
NSMutableArray *listOfItems;
NSMutableArray *appleComputers,*otherComputers;
UIScrollView *scrollView;
}
#end
(this is your .m file)
- (void)viewDidLoad {
[super viewDidLoad];
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 600)];
scrollView.delegate = self;
scrollView.backgroundColor = [UIColor grayColor];
scrollView.contentSize = CGSizeMake(300, 800);
appleComputers = [[NSMutableArray alloc] init]; // I made it by my style
[appleComputers addObject: #"iPhone"];
[appleComputers addObject:#"iPod"];
[appleComputers addObject:#"MacBook"];
[appleComputers addObject:#"MacBook Pro"];
otherComputers = [[NSMutableArray alloc] init];
[otherComputers addObject: #"HP"];
[otherComputers addObject:#"Dell"];
[otherComputers addObject:#"Windows"];
[otherComputers addObject:#"Sony"];
[otherComputers addObject:#"Ivory"];
[otherComputers addObject:#"IBM"];
self.navigationItem.title = #"Computers";
// Create a table
tblSimpleTable.delegate = self;
CGRect cgRct = CGRectMake(10, 50, 300, 600);
tblSimpleTable = [[UITableView alloc] initWithFrame:cgRct
style:UITableViewStyleGrouped]; // Initilize the table
[tblSimpleTable setBackgroundColor:[UIColor blackColor]];
tblSimpleTable.sectionHeaderHeight = 30.0;
tblSimpleTable.sectionFooterHeight = 30.0;
tblSimpleTable.scrollEnabled = NO;
tblSimpleTable.delegate = self;
tblSimpleTable.dataSource = self;
[scrollView addSubview:tblSimpleTable];
self.view = scrollView;
//Create the header
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 60)];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, 300, 40)];
headerLabel.text = NSLocalizedString(#"Header for the table", #"");
headerLabel.textColor = [UIColor whiteColor];
headerLabel.shadowColor = [UIColor yellowColor];
headerLabel.shadowOffset = CGSizeMake(0, 1);
headerLabel.font = [UIFont boldSystemFontOfSize:22];
headerLabel.backgroundColor = [UIColor clearColor];
[containerView addSubview:headerLabel];
tblSimpleTable.tableHeaderView = containerView;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section == 0)
return [appleComputers count];
else if(section == 1)
return [otherComputers count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
reuseIdentifier:CellIdentifier] autorelease];
}
if(indexPath.section == 0)
cell.text = [NSString stringWithFormat:#"%#“,
[appleComputers objectAtIndex:indexPath.row]];
else if(indexPath.section == 1)
cell.text = [NSString stringWithFormat:#"%#“,
[otherComputers objectAtIndex:indexPath.row]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath
{
// do whatever here
}
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.
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.
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.