In my iPhone application, I have a UITableView and this contains a UIImageView, button and Label. I am updating my database as per the values from the server and updating the details in the tableview. If I run the app for second time, after some modification at the server, the imageview is not getting updated. Button and label are updating. When I checked the local path for the image from the database, it shows the new image in the documents folder but the table cell still shows the old one. To the see the updated image, I should reinstall the app. What should I do to fix this issue?
Here is the work flow of what I did:
Loading new values from the database, and keeping all the values in an array
Removing the tableview
Creating the tableview again
Reload tableview.
Edit
//creating custom cell for the table view for displaying different objects
- (UIMenuItemCell *) getCellContentView:(NSString *)cellIdentifier {
CGRect CellFrame = CGRectMake(0, 0, 150, 60);
CGRect Label1Frame = CGRectMake(20, 23, 98, 30);
CGRect imgFrame = CGRectMake(20, 48, 110, 123);
CGRect btnFrame = CGRectMake(25, 136, 100, 30);
UILabel *lblTemp;
UIImageView *itemImg;
UIButton *itemBtn;
UIMenuItemCell *cell = [[UIMenuItemCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.frame = CellFrame;
//Initialize Label with tag 1.
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
lblTemp.tag = 1;
lblTemp.textColor=[UIColor colorWithRed:139.0f/255.0f green:69.0f/255.0f blue:19.0f/255.0f alpha:1.0f];
lblTemp.textAlignment = UITextAlignmentCenter;
lblTemp.backgroundColor = [UIColor clearColor];
lblTemp.font = [UIFont systemFontOfSize:13.0];
[cell.contentView addSubview:lblTemp];
[lblTemp release];
//Initialize ImageView
itemImg = [[UIImageView alloc]initWithFrame:imgFrame];
itemImg.tag = 2;
[cell.contentView addSubview:itemImg];
[itemImg release];
//Initialize Button
itemBtn = [[UIButton alloc]initWithFrame:btnFrame];
itemBtn.frame = btnFrame;
itemBtn.tag = 3;
itemBtn.titleLabel.textColor = [UIColor blueColor];
itemBtn.titleLabel.font = [UIFont systemFontOfSize:9.0];
[cell.contentView addSubview:itemBtn];
[itemBtn release];
return cell;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d", indexPath.row];
UIMenuItemCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [self getCellContentView:CellIdentifier];
cell.transform = CGAffineTransformMakeRotation(M_PI_2);
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.cellItemName = (UILabel *)[cell viewWithTag:1];
cell.cellitemImage = (UIImageView *)[cell viewWithTag:2];
cell.cellItemButton = (UIButton *)[cell viewWithTag:3];
DataBaseClass *itemObj = [appDelegate.itemArray objectAtIndex:indexPath.row];
NSString *imageLocalFilePath = nil;
if ([[tempitemStatusArray objectAtIndex:indexPath.row] isEqualToString:#"NotAvailable"]) {
cell.cellItemProgress.hidden = YES;
cell.cellItemButton.hidden = NO;
imageLocalFilePath = [NSString stringWithFormat:#"%#",[tempItemLocalNotAvailPath objectAtIndex:indexPath.row]];
NSString *date = [self changeDateFormat:itemObj.itemReleaseDate];
[cell.cellItemButton setTitle:date forState:UIControlStateNormal];
cell.cellItemButton.userInteractionEnabled = NO;
cell.userInteractionEnabled = NO;
[cell.cellItemButton removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents];
[cell.cellItemButton setBackgroundImage:[UIImage imageNamed:#"not_available_bttn_bck_img"] forState:UIControlStateNormal];
}else if ([[tempitemStatusArray objectAtIndex:indexPath.row] isEqualToString:#"Available"]){
cell.cellItemButton.userInteractionEnabled = YES;
cell.userInteractionEnabled = YES;
cell.cellItemProgress.hidden = YES;
[cell.cellItemButton setTitle:#"" forState:UIControlStateNormal];
[cell.cellItemButton setBackgroundImage:[UIImage imageNamed:#"available_bttn_img_normal"] forState:UIControlStateNormal];
[cell.cellItemButton setBackgroundImage:[UIImage imageNamed:#"available_bttn_img_pressed"] forState:UIControlStateHighlighted];
[cell.cellItemButton removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents];
[cell.cellItemButton addTarget:self action:#selector(confirmationAlert:) forControlEvents:UIControlEventTouchUpInside];
imageLocalFilePath = [NSString stringWithFormat:#"%#",[tempItemLocalAvailPath objectAtIndex:indexPath.row]];
}
if ([imageLocalFilePath isEqualToString:#""]) {
[cell.cellitemImage setImage:[UIImage imageNamed:#"item01.png"]];
}else {
[cell.cellitemImage setImageWithURL:[NSURL fileURLWithPath:imageLocalFilePath] placeholderImage:[UIImage imageNamed:#"item01.png"]];
}
cell.cellItemName.text = [NSString stringWithFormat:#"%#",[tempItemNameArray objectAtIndex:indexPath.row]];
}
return cell;
}
Please help.
I found the issue, in the cellForRowAtIndexPath method, for setting the image, I used the code
[cell.cellitemImage setImageWithURL:[NSURL fileURLWithPath:imageLocalFilePath] placeholderImage:[UIImage imageNamed:#"item01.png"]];
I used a external classes calls ImageLoading for loading the images and that classes included some cache methods, and that caused the issue. So I changed that line to
[cell.cellitemImage setImage:[UIImage imageWithContentsOfFile:imageLocalFilePath]];
that solved the issue.
Thanks for your support :)
There should be a
}
after the line
cell.cellItemButton = (UIButton *)[cell viewWithTag:3];
i took jet a first look at your code, and i found out this "error":
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d", indexPath.row];
so... it won't give you any error, it works...
but that's against how table works:
doing this you are creating and allocating a new cell for each item of your array/database,
meaning that if you need to scroll to see 1.000 items, you create 1.000 cells!!!
it shouldn't be like this.
Normally a table just creates only the cells needed to be shown on the screen/display
meaning that if your table area is 300 pixel in height and each cell is 30 pixel height,
then you may need only 11 cells, and you should use/allocate only 11 cells, not 1.000
the magic of cells is to reuse cells when user scrolls them out of screen (e.g. UP), to set it's data and images with the new item data and to put it again on screen (e.g. DOWN)
thats what CellIdentifier is normally used for, and it should be the same for all cells in a table (at least if all cells are similar, but the contained data, and you don't need different cells)
allocating too many cells could give you memory problems, if you manage too much items...
p.s.
i'm probably not answering to your question, there may be other problems in your code, as i said i just read it in hurry
you will have to keep some time delay between laoding your data from databse and tableview reload. you will then able to see the updated image.
Related
Please help me writing good code
My Scenario:
loading image in tableview from custom image array(size can be 1-1000 or may be more)- Done
Placed Image on Button-Done (Dont know right way but working fine)
Getting Image tag with the help of button-Done
Not to load extra images in cell (suppose 4 image view in one cell and 26 images)-Done
I am Loading Images in UItableView but app only crashing in device, working fine in simulator. i have googled and found some answer on reusing cell modified my code accordingly to some extent. But i am still not sure about that image loading and crashing. Some time when the image are less it crash on scrolling and some time just after loading images in table view.
I am close to my solution but not getting good result. Please Help!!
Please check my code and modify it if required
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *CellIdentifier =[NSString stringWithFormat:#"%i-%i", indexPath.section,indexPath.row];
// static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]autorelease];
NSInteger imageIndex = [indexPath row] * 4;
NSInteger size = [imageArray count];
imageView1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 80,80)];
imageView1.image = [imageArray objectAtIndex:imageIndex];
aButton1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[aButton1 setTag:imageIndex];
[aButton1 setImage:imageView1.image forState:UIControlStateNormal];
aButton1.frame = CGRectMake(0, 0, 80,80);
[aButton1 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:aButton1];
if (size == imageIndex +1) {
return cell;
}
imageView2 = [[UIImageView alloc] initWithFrame:CGRectMake(80, 0, 80,80)];
// imageView2.tag= tagValue+2000;
imageView2.image = [imageArray objectAtIndex:imageIndex+1];
[cell.contentView addSubview:imageView2];
UIButton* aButton2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[aButton2 setTag:imageIndex+1];
[aButton2 setImage:imageView2.image forState:UIControlStateNormal];
aButton2.frame = CGRectMake(80, 0, 80,80);
[aButton2 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:aButton2];
if (size == imageIndex + 2) {
return cell;
}
imageView3 = [[UIImageView alloc] initWithFrame:CGRectMake(160, 0, 80,80)];
imageView3.image = [imageArray objectAtIndex:imageIndex+2];
UIButton* aButton3 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[aButton3 setTag:imageIndex+2];
[aButton3 setImage:imageView3.image forState:UIControlStateNormal];
aButton3.frame = CGRectMake(160, 0, 80,80);
[aButton3 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:aButton3];
if (size == imageIndex + 3) {
return cell;
}
imageView4 = [[UIImageView alloc] initWithFrame:CGRectMake(240, 0, 80,80)];
imageView4.image = [imageArray objectAtIndex:imageIndex+3];
UIButton* aButton4 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[aButton4 setTag:imageIndex+3];
[aButton4 setImage:imageView4.image forState:UIControlStateNormal];
aButton4.frame = CGRectMake(240, 0, 80,80);
[aButton4 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:aButton4];
}
else
{
NSLog(#"old one");
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
return cell;
}
The problem is with this line
NSString *CellIdentifier =[NSString stringWithFormat:#"%i-%i", indexPath.section,indexPath.row];
Each of the row is created and none of the cells are reused except when scrolling back to already displayed cells.
A better way would be to take advantage of reuse of cells by using a identifier to give a cell back when it goes out of view and then styling it according to the requirement. More like NSString *CellIdentifier =#"MyCellIdentifier";
Now check the section and row for the cell and style it accordingly.
I think size of the image matters. Can you try loading with image of very small size say less than 5kb and see (just for testing purpose) ?
I want to add more than one image in table view.
I can add one image using cell.imageview.image.
but how to add one more image.
And I also want to add buttons in all cells.
How can I do that ?
You should make your own UITableViewCell subclass. There are many tutorials for that:
http://iphone.zcentric.com/2008/08/05/custom-uitableviewcell/
http://www.icodeblog.com/2009/05/24/custom-uitableviewcell-using-interface-builder/
http://www.e-string.com/content/custom-uitableviewcells-interface-builder
Including:
http://stackoverflow.com
http://www.google.com
Make your own UITableViewCell subclass.
Use a UITableView with a custom cell with whatever you want in it, load extra images and labels. To get the custom cell, create an IBOutlet to the cell and use this method.
[[NSBundle mainBundle] loadNibNamed:#"customCellView" owner:self options:nil];
To make a cell, make a new Nib/Xib file which is blank, make files owner the class with the cells, drag a UITableviewcell object out and put whatever objects you want on top of that view, set background as clear color and when you load the nib, enter all info into those images and labels. GL
Here is a block of code I use alot in my apps. Its not the fastest way to implement, but it gives you complete control over how the cell looks and whats in it. Using the code below you can see how my app looks. You have 2 buttons on one cell. They both do something different when pushed, and if the actual CELL is selected I do something else. I removed some of the code because im sure you dont care about what Im doing when the cell is selected, only how to get the buttons on, and know which one is pushed.
-(void)scheduleServiceButtonPressed:(id)sender {
//when the user click the button "service appt" on a table cell, we get the cellRow and use that to identify which car to show
ServiceApptViewController * vc = (ServiceApptViewController *)[[ServiceApptViewController alloc] init];
vc.cameFromGarageSelectionInt = [sender tag]; // here is the cell row that was selected.
[self.navigationController pushViewController:vc animated:YES];
[vc release];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 70;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [app.savedUserVehicleArray count];
}
// 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];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
}
cell = [self getCellContentView:CellIdentifier:indexPath.row];
[cell setBackgroundColor:[UIColor redColor]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSLog(#"out cells for index");
return cell;
}
- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier:(int)cellIndex {
NSLog(#"in content");
vehicleForRow = [app.savedUserVehicleArray objectAtIndex:cellIndex];
//CGRect CellFrame = CGRectMake(0, 0, 300, 60);
CGRect CellFrame = CGRectMake(0, 0, 320, 70);
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:cellIdentifier] autorelease];
// put a UIView underneath for coloring
UIView * view = [[UIView alloc] initWithFrame:CellFrame];
if ( cellIndex%2 == 0 ){
view.backgroundColor = [UIColor whiteColor];
}else{
//view.backgroundColor = [UIColor colorWithRed:0.98 green:0.92 blue:0.52 alpha:1.0];
view.backgroundColor = [UIColor colorWithRed:.238 green:.238 blue:0.238 alpha:.10];
}
[cell.contentView addSubview:view];
[view release];
if (vehicleForRow.isDefault && [vehicleForRow.isDefault compare:#"YES"]==0) {
//add green check mark if vehicle is default
UIImageView * bgimage3 = [[UIImageView alloc] initWithFrame:CGRectMake(245, 15, 40, 32)];
bgimage3.image = [UIImage imageNamed:#"greenCheckMark.png"];
[cell.contentView addSubview:bgimage3];
[bgimage3 release];
//default vehicle label
UILabel *lblTemp;
NSString * z = [NSString stringWithFormat:#"Default"];
NSString * s1 = z;
CGRect Label1Frame = CGRectMake(240, 43, 250, 25); // name
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
lblTemp.adjustsFontSizeToFitWidth = TRUE;
lblTemp.text = s1;
lblTemp.font = [UIFont boldSystemFontOfSize:12];
lblTemp.textColor = [UIColor blueColor];
lblTemp.backgroundColor = [UIColor clearColor];
[lblTemp setTextAlignment:UITextAlignmentLeft];
[cell.contentView addSubview:lblTemp];
}
else {
UIImageView * bgimage3 = [[UIImageView alloc] initWithFrame:CGRectMake(250, 15, 30, 24)];
bgimage3.image = [UIImage imageNamed:#"grayCheckMark.png"];
[cell.contentView addSubview:bgimage3];
[bgimage3 release];
UILabel *lblTemp;
NSString * z = [NSString stringWithFormat:#"Set As Default"];
NSString * s1 = z;
CGRect Label1Frame = CGRectMake(233, 38, 250, 25); // name
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
lblTemp.adjustsFontSizeToFitWidth = TRUE;
lblTemp.text = s1;
lblTemp.font = [UIFont boldSystemFontOfSize:8];
lblTemp.textColor = [UIColor grayColor];
lblTemp.backgroundColor = [UIColor clearColor];
[lblTemp setTextAlignment:UITextAlignmentLeft];
[cell.contentView addSubview:lblTemp];
}
// add service button to each cell
UIImage *image;
schedServiceButton = [UIButton buttonWithType:UIButtonTypeCustom];
image = [UIImage imageNamed:#"tableServiceButton.png"];
[schedServiceButton setBackgroundImage:image forState:UIControlStateNormal];
schedServiceButton.frame = CGRectMake(5, 30, 97, 35);
[schedServiceButton setTag:cellIndex];//this is how we know which cell button was pressed
[schedServiceButton addTarget:self action:#selector(scheduleServiceButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
schedServiceButton.titleLabel.font = [UIFont systemFontOfSize:12];
[schedServiceButton.titleLabel setLineBreakMode:UILineBreakModeCharacterWrap];
[schedServiceButton setTitle:#"Schedule\nService Appt." forState:UIControlStateNormal];
schedServiceButton.titleLabel.textAlignment = UITextAlignmentCenter;
[cell.contentView addSubview:schedServiceButton];
//yes add owners manual button
viewOMButton = [UIButton buttonWithType:UIButtonTypeCustom];
image = [UIImage imageNamed:#"tableOMButton.png"];
[viewOMButton setBackgroundImage:image forState:UIControlStateNormal];
viewOMButton.frame = CGRectMake(105, 30, 97, 35);
[viewOMButton setTag:cellIndex];
[viewOMButton addTarget:self action:#selector(viewOwnersManualButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
viewOMButton.titleLabel.font = [UIFont systemFontOfSize:12];
[viewOMButton.titleLabel setLineBreakMode:UILineBreakModeCharacterWrap];
[viewOMButton setTitle:#"View\nOwner's Manual" forState:UIControlStateNormal];
viewOMButton.titleLabel.textAlignment = UITextAlignmentCenter;
[cell.contentView addSubview:viewOMButton];
//car description label
UILabel *lblTemp;
NSString * z = [NSString stringWithFormat:#"%# %# %#",vehicleForRow.userVehicleYear,vehicleForRow.userVehicleMake,vehicleForRow.userVehicleModel];
NSString * s1 = z;
CGRect Label1Frame = CGRectMake(10, 5, 250, 25); // name
//Initialize Label with tag 1.
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
lblTemp.adjustsFontSizeToFitWidth = TRUE;
lblTemp.text = s1;
lblTemp.font = [UIFont boldSystemFontOfSize:16];
lblTemp.textColor = [UIColor blueColor];
lblTemp.backgroundColor = [UIColor clearColor];
[lblTemp setTextAlignment:UITextAlignmentLeft];
[cell.contentView addSubview:lblTemp];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
}
hi all i implemented customized UITableViewcell with the below code.Each cell loaded with four images..
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *hlCellID = #"hlCellID";
UITableViewCell *hlcell = [tableView dequeueReusableCellWithIdentifier:hlCellID];
if(hlcell == nil) {
hlcell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:hlCellID] autorelease];
hlcell.accessoryType = UITableViewCellAccessoryNone;
hlcell.selectionStyle = UITableViewCellSelectionStyleNone;
[hlcell.contentView removeAllSubViews];
}
//NSLog(#"the scetions is %#",sections);
int section = indexPath.section;
for(int i=0;i<4;i++){
CGRect rect = CGRectMake(18+192*i, (4*indexPath.row)+50, 120, 150);
if ((4*indexPath.row)+i>=[self.imagesToDisplay count]) {
break;
}
UIImage *imageToDisplay=[UIImage imageWithData:[self.imagesToDisplay objectAtIndex:(4*indexPath.row)+i]];
NSLog(#"The size of the image is:%#",NSStringFromCGSize(imageToDisplay.size));
UIButton *button=[[UIButton alloc] initWithFrame:rect];
[button setFrame:rect];
[button setBackgroundImage:imageToDisplay forState:UIControlStateNormal];
[button setContentMode:UIViewContentModeCenter];
NSString *tagValue = [NSString stringWithFormat:#"%d%d",indexPath.row,i];
NSLog(#"the tag is %#",tagValue);
button.tag = [tagValue intValue];
NSLog(#"....tag....%d", button.tag);
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[hlcell.contentView addSubview:button];
[button release];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(18+192*i,(4*indexPath.row)+100+70 , 100, 100)] ;
label.text = #"price $0.99";
label.textColor = [UIColor blackColor];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
label.font = [UIFont fontWithName:#"ArialMT" size:12];
[hlcell.contentView addSubview:label];
[label release];
}
return hlcell;
}
for each image acts as uibutton.i am trying to load around 1000 images.these images i am taking from the server.when one image is loaded to my app i am updating total cell.
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:ceil((float)[gridView.imagesToDisplay count]/4)-1 inSection:0];
NSArray *cellIndexPath=[NSArray arrayWithObjects:indexPath,nil];
[gridView.tableview reloadRowsAtIndexPaths:cellIndexPath withRowAnimation:UITableViewRowAnimationNone];
upto now my code is working fine and when i am trying to scroll many times after loading all the images its getting crash.and my GDB showing as memory warning.can any one suggest me why the issue happening.Thanks for your response in advance.
It looks like you always allocate new Images and display them on the Cell, but you never actually release the images when the cell is no longer displayed.
The definition for the UITableView cell states, that as soon a cell is no longer used it is purged and prepared for a new content. In your code you always add new subviews to the cell, but never actually release the content.
The best solution to your problem is to implement a UITableViewCell by subclassing it and manually set the images. Furthermore implement the
- (void)prepareForReuse
method of the class to release the images that are currently displayed. See the reference for more documentation of UITableViewCell
I have created a check box using the uiimageview and i have placed the checkbox into the uitableview cell like below
i want to get indexpath.row when i check the check box.
so i added the uiimageviiew inside the cell. so the didSelectRowAtIndexPath is gets called and gives me the indexpath.row.
but when the row is selected i want to show the detailed view.
now this runs me into trouble.
so can you people suggest me how to tackle my above problem.
when i check the checkbox i want to get the indexpath.row.
and when the row is selected i need to show the detailed view.
Thanks for your time and help
UPDATE 1 :
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
profileName = [appDelegate.archivedItemsList objectAtIndex:indexPath.row];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"xc"] autorelease];
cb = [[UIButton alloc] initWithFrame:CGRectMake(5,10, unselectedImage.size.width, unselectedImage.size.height)];
[cb setImage:unselectedImage forState:UIControlStateNormal];
[cb setImage:selectedImage forState:UIControlStateSelected];
[cb addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchDown];
[cell.contentView addSubview:cb];
}
if ( tableView == myTableView )
{
titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(60, 0, 150, 35)];
titleLabel.font = [UIFont boldSystemFontOfSize:13];
titleLabel.textColor = [UIColor blackColor];
[cell.contentView addSubview:titleLabel];
NSString *subjectData = [profileName.archive_subject stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
[titleLabel setText:[NSString stringWithFormat: #"%# ", subjectData]];
lblDescription = [[UILabel alloc]initWithFrame:CGRectMake(60, 30, 210, 30)];
lblDescription.numberOfLines = 2;
lblDescription.lineBreakMode = YES;
lblDescription.adjustsFontSizeToFitWidth = YES;
lblDescription.font = [UIFont systemFontOfSize:10];
lblDescription.textColor = [UIColor grayColor];
[cell.contentView addSubview:lblDescription];
NSString *CompanyName = [profileName.archive_content stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
[lblDescription setText:[NSString stringWithFormat: #"%# ", CompanyName]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
return cell;
}
Use a UIButton instead of UIImageView for your checkbox - this way you can add an action/method to it, where you can grab the indexPath, plus you can add different images for selected/unselected state which will eliminate all the confusing stuff happening in your code above:
So in your cellForRowAtIndexPath: method:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...// Your existing code here
UIImage *unselectedCheckboxImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"unselectedImageName" ofType:#"imageType"]];
UIImage *selectedCheckboxImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"selectedImageName" ofType:#"imageType"]];
UIButton *cb = [[UIButton alloc] initWithFrame:CGRectMake(desiredX, desiredY, unselectedCheckboxImage.frame.size.width, unselectedCheckboxImage.frame.size.height)];
[cb setImage:unselectedCheckboxImage forState:UIControlStateNormal];
[cb setImage:selectedCheckboxImage forState:UIControlStateSelected];
[cb addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchDown];
[cell.contentView addSubview:cb];
[cb release];
}
And then for your button action method:
- (IBAction)buttonAction:(id)sender
{
if ([sender isKindOfClass:[UIButton class]])
{
UIButton *checkboxButton = (UIButton*)sender;
checkboxButton.selected = !checkboxButton.selected;
NSIndexPath *indexPath = [self.myTableView indexPathForCell:(UITableViewCell*)[[checkboxButton superview] superview]];
// Do whatever you like here
}
}
I think your logic is causing the problem in the didSelectRowAtIndexPath: method; make sure that's right. Besides, if you just want to use check mark for the cell I think it's better if you use UITableViewCellAccessoryCheckmark. This may give you a basic idea.
I have this code below to populate my UITableView on the fly.
I have to display two kind of cells: a regular cell with a background image and a cell with a regular background image, plus a label and a button.
if Indexpath.row is less than a control variable, then regular cells are drawn. If not, cells with buttons and labels are drawn.
this is the code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
UIImage *imageU;
if (indexPath.row < controlVariable) {
imageU = [[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:[NSString stringWithFormat: #"table%d", indexPath.row] ofType:#"jpg"]] autorelease];
cell.imageView.image = imageU;
} else {
imageU = [[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:[NSString stringWithFormat: #"table-pg%d",numberX]
ofType:#"jpg"]] autorelease];
cell.imageView.image = imageU;
NSString * myString = [NSString stringWithFormat: #"pago%d", numberX];
UILabel * myLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 49.0, 200.0, 22.0)];
[myLabel setTextAlignment:UITextAlignmentLeft];
[myLabel setBackgroundColor:[UIColor blueColor]];
[myLabel setClipsToBounds:YES];
[myLabel setFont:[UIFont systemFontOfSize:14.0]];
[myLabel setTextColor:[UIColor blackColor]];
[myLabel setText: myString];
[myLabel setAlpha:0.6];
[cell addSubview: myLabel];
[myLabel release];
UIButton *buyButton = [[UIButton alloc] initWithFrame:CGRectMake( 220, 4, 100, 35)];
buyButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
buyButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[buyButton setTitle:NSLocalizedString(#"buyKey", #"") forState:UIControlStateNormal];
[buyButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
buyButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];
UIImage *newImage = [[[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource: #"whiteButton" ofType:#"png"]] autorelease]
stretchableImageWithLeftCapWidth:12.0f topCapHeight:0.0f];
[buyButton setBackgroundImage:newImage forState:UIControlStateNormal];
[buyButton addTarget:self action:#selector(comprar:) forControlEvents:UIControlEventTouchDown];
buyButton.backgroundColor = [UIColor clearColor];
[buyButton setTag:indexPath.row];
[cell addSubview:buyButton];
[buyButton release];
}
return cell;
}
The problem with this code is: when I scroll the UITableView down and reach the division between regular cells and cells with buttons and labels, I see it is rendering correctly, but if I go up after going deep down, I see the buttons and labels being added to cells that were not supposed to have them. From this point forward, all cells contains buttons and labels...
It is like the cells are not releasing its contents before drawing. It is like labels and buttons are being added on top of other buttons and labels already on the cell. Cells are not releasing its contents before drawing again.
How to solve that?
thanks for any help.
NOTE: I see barely no difference after making the changes suggested by the two first answers. Now, not all cells are wrong, just some. They change every time I scroll down the table and return to the beginning of the table.
You should use a separate reuseIdentifier for each cell 'type' that you are using. In this case, you'll want to use two.
You'll also want to create/add the UILabel and UIButton when you get a dequeue miss and not for every run through.. In pseudocode:
UILabel * lbl;
UIButton * btn;
cell = [table dequeueReusableCellWithIdentifier:correctIdentifier];
if (cell == nil)
{
cell = ...; // alloc cell
lbl = ...;
lbl.tag = kTagLabel;
[cell addSubView:lbl];
btn = ...;
btn.tag = kTagButton;
[cell addSubView:btn];
}
else
{
lbl = (UILabel*)[cell viewWithTag:kTagLabel];
btn = (UIButton*)[cell viewWithTag:kTagButton];
}
//... now set the text/image appropriately.
Otherwise, you create a label and button each time the cell is dequeued from the table. Scrolling up and down will cause lots of labels and buttons to be created that never get released.
You should use two different reuseIdentifiers; one for cells with just images, and one for cells with images and buttons. The problem is that your one cell type is being reused, but its content is not (nor should it be) cleared out when it's dequeued.