My problem is I have a Custom button and ImageView to which I added the Image.I made this imageView to the custom button as a subview.when Im running it in simulator it workin fine,but when Im runnig it in Device it was not displaying the image in the button.
I written the code as:
In cellForRowtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MasterViewIdentifier"];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"MasterViewIdentifier"] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIView* elementView = [[UIView alloc] initWithFrame:CGRectMake(20,170,320,280)];
elementView.tag = 0;
elementView.backgroundColor=[UIColor clearColor];
[cell.contentView addSubview:elementView];
[elementView release];
}
UIView* elementView = [cell.contentView viewWithTag:0];
elementView.backgroundColor=[UIColor clearColor];
for(UIView* subView in elementView.subviews)
{
[subView removeFromSuperview];
}
if(indexPath.section == 8)
{
imageView.image = [UIImage imageNamed:#"yellow_Star.png"];
MyCustomButton *button1 = [[MyCustomButton alloc]initWithRating:1];
[button1 setFrame:CGRectMake(159, 15, 25, 20)];
[button1 setShowsTouchWhenHighlighted:YES];
[button1 addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
[button1 addSubview:imageView];
[elementView addSubview:button1];
[button1 release];
[imageView release];
}
return cell;
}
and in my buttonAction:
-(void)buttonAction:(MyCustomButton*)sender
{
rating = [sender ratingValue];
event.eventRatings = rating;
[tableView reloadData];
}
and i MyCustomButton class:
i have a method as
-(MyCustomButton*) initWithRating:(NSInteger)aRatingValue
{
if (self = [super init])
{
self.ratingValue = aRatingValue;
}
return self;
}
pls help guys from dis problem.
Thank you,
Monish.
You're trying to load image named "yellow_Star.png" - check if it actually named so (with the same characters case). File system on iPhone is case sensitive and on Mac OS is not - so it is often causes such problems and file names is the first thing to look at.
Edit: You can also try to check if the image is present in the application bundle - may be it was removed from copy resources build step by chance, that is your image must be in a "Copy Bundle Resources" build step for your build target. If it is absent you can just drag and drop your image there.
Related
I have seen some posts before, but didn't get the answer yet, thats why i am trying to post again in more effective manner. How can i use check-uncheck functionality in UITableView like below image.
This is table i want when i click on button of any cell, that buttons image will change, not on all cells.
For Check-Uncheck functionality only buttonClicked: method is not enough. You will have also put the condition in cellForRowAtIndexPath: method for which button is selected or which in unselected because cellForRowAtIndexPath: method will call each time when you will scroll your UITableView and cells will be refresh.
And i saw your previous question you're adding two buttons with two action not a good way just change the image of button for check-uncheck.
So here is what i do for this -
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
{
IBOutlet UITableView *tblView;
NSMutableArray *arrayCheckUnchek; // Will handle which button is selected or which is unselected
NSMutableArray *cellDataArray; // this is your data array
}
#end
Now in ViewController.m class -
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arrayCheckUnchek = [[NSMutableArray alloc]init];
//Assign your cell data array
cellDataArray = [[NSMutableArray alloc]initWithObjects:#"cell-1",#"cell-2",#"cell-3",#"cell-4",#"cell-5", nil];
// setting all unchecks initially
for(int i=0; i<[cellDataArray count]; i++)
{
[arrayCheckUnchek addObject:#"Uncheck"];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [cellDataArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [cellDataArray objectAtIndex:indexPath.row];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(270.0, 7.0, 30.0, 30.0)];
if([[arrayCheckUnchek objectAtIndex:indexPath.row] isEqualToString:#"Uncheck"])
[button setImage:[UIImage imageNamed:#"uncheck_icon"] forState:UIControlStateNormal];
else
[button setImage:[UIImage imageNamed:#"check_icon"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
return cell;
}
-(void)buttonClicked:(id)sender
{
//Getting the indexPath of cell of clicked button
CGPoint touchPoint = [sender convertPoint:CGPointZero toView:tblView];
NSIndexPath *indexPath = [tblView indexPathForRowAtPoint:touchPoint];
// No need to use tag sender will keep the reference of clicked button
UIButton *button = (UIButton *)sender;
//Checking the condition button is checked or unchecked.
//accordingly replace the array object and change the button image
if([[arrayCheckUnchek objectAtIndex:indexPath.row] isEqualToString:#"Uncheck"])
{
[button setImage:[UIImage imageNamed:#"check_icon"] forState:UIControlStateNormal];
[arrayCheckUnchek replaceObjectAtIndex:indexPath.row withObject:#"Check"];
}
else
{
[button setImage:[UIImage imageNamed:#"uncheck_icon"] forState:UIControlStateNormal];
[arrayCheckUnchek replaceObjectAtIndex:indexPath.row withObject:#"Uncheck"];
}
}
And finally it will look like -
Tags are useful with customised uitableviewcell designed in IB. If you create cells programmatically, you don't need tags. You use them only to find correct uiview to set properties.
Yes this is simple to set Tags while declaring the classes inside UITableViewCell and identify them using tags. I have posted some sample code for your reference. Am not sure it will solve your problem. You asked how to set tags and identify the classes using tags. So it will give you some basic idea about your question.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
label1 = [[UIView alloc] initWithFrame:CGRectMake(2, 20, 15, 15)];
label1.tag = 100;
label1.backgroundColor = [UIColor whiteColor];
label1.layer.cornerRadius = 5;
[cell.contentView addSubview: label1];
label2 = [[UILabel alloc] initWithFrame:CGRectMake(25, 2, 165, 23)];
label2.tag = 101;
label2.font = [UIFont boldSystemFontOfSize:15];
label2.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview: label2];
label3 = [[UILabel alloc] initWithFrame:CGRectMake(190, 2, 90, 23)];
label3.tag = 102;
label3.font = [UIFont systemFontOfSize:14];
label3.textColor = [UIColor colorWithRed:0.14117670588235 green:0.435294117647059 blue:0.847058823529412 alpha:1];
label3.backgroundColor = [UIColor clearColor];
label3.textAlignment = UITextAlignmentRight;
[cell.contentView addSubview: label3];
}
label1 = (UILabel *) [cell.contentView viewWithTag:100];
NSString *string1 = [array1 objectAtIndex:indexPath.row];
label2 = (UILabel *) [cell.contentView viewWithTag:101];
NSString * string2 = [array2 objectAtIndex:indexPath.row];
label3 = (UILabel *) [cell.contentView viewWithTag:102];
NSString * string3 = [array3 objectAtIndex:indexPath.row];
return cell;
}
Please let me know this is useful or not. Otherwise we'll go to some other way.
Happy Coding. Thanks.
i agree with #VakulSaini because u can do this to handle which cell touch or swipe or what ever and this is an ex:
-(void)handleSwipLeft:(UISwipeGestureRecognizer *)gestureRecognizer
{
CGPoint Location = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:Location];
cell = [tableView cellForRowAtIndexPath:indexPath];
}
Use cellForRowAtIndexPath method of UITableView and in This method Add any component like (UITextField,UILabel ..... etc ) In your UITableViewCell by using [cell.contentView addSubview:YourComponentName]; and give each component to its tag by indexPath.row.
such like ,,,
YourComponentName.tag = indexPath.row;
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.
I have a tableview where I am displaying my values from database in tableview cells. In this tableview cellforrowatindexpath, I have created a button with an image on it and set selector for it. So when I click on the button my selector is called and it changes my image to another image.
But the problem is it does not identifies the indexpath i.e. if 4 rows are present in the tableview and if I click on the first row button, its image should change but problem is 4th row action is performed and its image is changed because it does not get the proper indexpath of the image to change.
This is my cellforrowatindexpath code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d%d", indexPath.section, indexPath.row];
appDelegate = (StopSnoozeAppDelegate*)[[UIApplication sharedApplication]delegate];
cell =(TAlarmCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[TAlarmCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
mimageButton = [UIButton buttonWithType:UIButtonTypeCustom];
mimageButton.frame=CGRectMake(10, 20, 20, 20);
mimageButton.tag = 1;
onButtonView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 30, 50)];
onButtonView.tag = 2;
onButtonView.image = [UIImage imageNamed:#"alarm_ON.png"];
[mimageButton setImage:onButtonView.image forState:UIControlStateNormal];
[cell.contentView addSubview:mimageButton];
[mimageButton addTarget:self action:#selector(changeMapType::) forControlEvents:UIControlEventTouchUpInside];
}
return cell;
}
This is my changemapType code
-(void)changeMapType:(NSIndexPath*)path1:(UIButton*)sender{
appDelegate.changeimagetype =!appDelegate.changeimagetype;
if(appDelegate.changeimagetype == YES)
{
onButtonView.image = [UIImage imageNamed:#"alarm_OF.png"];
[mimageButton setImage:onButtonView.image forState:UIControlStateNormal];
appDelegate.changeimagetype = YES;
}
else
{
onButtonView.image = [UIImage imageNamed:#"alarm_ON.png"];
[mimageButton setImage:onButtonView.image forState:UIControlStateNormal];
appDelegate.changeimagetype = NO;
}
}
Don't break table view cell reuse just to put a different tag on each button. If your cells are the same, use the same reuse identifier.
You can find out the index path of the sender like this, without any need to mess around with tags. It also works for multi section tables.
CGPoint hitPoint = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *hitIndex = [self.tableView indexPathForRowAtPoint:hitPoint];
I don't think you can have additional arguments in an #selector like that. What you might have to do is subclass UIButton and add an NSIndexPath property (or even just an int) and in -(void)changeMapType:(MyCustomButton*)sender access the property there.
Also it seems you do not even use the index path in changeMapType so that will need to be changed as well.
EDIT: Is it the button image you are trying to change? In which case you don't need the index path at all, or a subclass. Just use [sender setImage:(UIImage *)image forState:(UIControlState)state].
Use yourTableView for getting the Index Path.. Try something like this.
- (void)buttonAction:(UIButton*)sender {
UITableViewCell *cell = (UITableViewCell*)button.superview;
NSIndexPath *indexPath = [yourTableView indexPathForCell:cell];
NSLog(#"%d",indexPath.row)
}
I think following code might help you..
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIView *myCheckbox = [[UIView alloc] init];
UIButton *myBt1 = [[UIButton alloc] initWithFrame:CGRectMake(10, 10, 30, 30)];
if([appDelegate.changeimagetype == YES"]){
[myBt1 setBackgroundImage:[UIImage imageNamed:#"alarm_ON.png"] forState:UIControlStateNormal];
}
else {
[myBt1 setBackgroundImage:[UIImage imageNamed:#"alarm_OF.png"] forState:UIControlStateNormal];
}
[myBt1 addTarget:self action:#selector(btcheckbox:) forControlEvents:UIControlEventTouchDown];
[myBt1 setTag:indexPath.row];
[myCheckbox addSubview:myBt1];
[myBt1 release];
[myCheckbox release];
[cell addsubview:myview];
return cell;
}
-(void) btcheckbox:(id) sender
{
UIButton *currentButton = (UIButton *) sender;
if([[currentButton backgroundImageForState:UIControlStateNormal] isEqual:[UIImage imageNamed:#"alarm_OF.png"]])
{
appDelegate.changeimagetype = YES;
[currentButton setBackgroundImage:[UIImage imageNamed:#"alarm_ON.png"] forState:UIControlStateNormal];
}else if([[currentButton backgroundImageForState:UIControlStateNormal] isEqual:[UIImage imageNamed:#"alarm_ON.png"]])
{
appDelegate.changeimagetype = NO;
[currentButton setBackgroundImage:[UIImage imageNamed:#"alarm_OF.png"] forState:UIControlStateNormal];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d", indexPath.row];
appDelegate = (StopSnoozeAppDelegate*)[[UIApplication sharedApplication]delegate];
cell =(TAlarmCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[TAlarmCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UIButton *mimageButton = [UIButton buttonWithType:UIButtonTypeCustom];
mimageButton.frame=CGRectMake(10, 20, 20, 20);
mimageButton.tag = indexPath.row;
//onButtonView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 30, 50)];
//onButtonView.tag = 2;
// onButtonView.image = [UIImage imageNamed:#"alarm_ON.png"];
[mimageButton setImage:[UIImage imageNamed:#"alarm_ON.png"] forState:UIControlStateNormal];
mimageButton.selected = NO;
[cell.contentView addSubview:mimageButton];
[mimageButton addTarget:self action:#selector(changeMapType:) forControlEvents:UIControlEventTouchUpInside];
}
return cell;
}
-(void)changeMapType:(UIButton*)sender{
if(sender.selected == YES)
{
// onButtonView.image = [UIImage imageNamed:#"alarm_OF.png"];
[sender setImage:[UIImage imageNamed:#"alarm_ON.png"] forState:UIControlStateNormal];
sender.selected = NO;
}
else
{
//onButtonView.image = [UIImage imageNamed:#"alarm_ON.png"];
[sender setImage:[UIImage imageNamed:#"alarm_OF.png"] forState:UIControlStateNormal];
sender.selected = YES;
}
}
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 a checkbox class that I want to toggle a boolean core data attribute from NO to YES. Drawing the actual checkbox and getting it to toggle isn't the issue, but persisting its state is. The checkbox is in the second view controller in my stack (RVC <--> ItemsVC (checkboxes are here) <--> ItemDetailVC). If I toggle the checkbox and then navigate either way, the state returns to unchecked.
I've tried a few ways to a) make the checkbox state persist and to b) make the state of the checkbox change the state of my boolean attribute from NO to YES.
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
[self setImage:[UIImage imageNamed:#"unchecked.png"] forState:UIControlStateNormal];
[self setImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateSelected];
[self addTarget:self action: #selector(checkboxTapped) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
- (IBAction) checkboxTapped {
if (self.isChecked == NO) {
self.isChecked = YES;
[self setImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateNormal];
self.selectedItem.inCart = isChecked;
} else {
self.isChecked = NO;
[self setImage:[UIImage imageNamed:#"unchecked.png"] forState:UIControlStateNormal];
}
}
isChecked is a BOOL that's declared in the header and selectedItem.inCart are my core data entity and boolean attribute, respectively.
EDIT: Here's the code in ItemsVC where the checkbox appears.
- (UITableViewCell *)tableView:(UITableView *)IVCTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [IVCTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
Item *item = [fetchedResultsController_ objectAtIndexPath:indexPath];
[self configureCell:cell withItem:item];
UILabel *itemLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 0, 100, 40)];
[cell.contentView addSubview:itemLabel];
itemLabel.text = item.itemName;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
Checkbox *checkbox = [[Checkbox alloc] initWithFrame:CGRectMake(10, 0, 70, 50)];
[cell.contentView addSubview:checkbox];
return cell;
}
EDIT 2: Here's the current state of my code, with comments about what works and what doesn't. At this point, the checkbox will check and uncheck, but the check will repeat every 10 rows, which I assume is where dequeueReusableCellWithIdentifier is doing its thing.
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
// If I don't set these images here, they don't appear in the table
[self setImage:[UIImage imageNamed:#"unchecked.png"] forState:UIControlStateNormal];
[self setImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateSelected];
[self addTarget:self action: #selector(checkboxTapped) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
// This function prevents checked checkboxes from unchecking
/*
- (void)setIsChecked:(BOOL)isChecked {
if (isChecked == isChecked_)
return;
[self setImage:[UIImage imageNamed:isChecked_?#"checked.png":#"unchecked.png"] forState:UIControlStateNormal];
self.selectedItem.inCart = [NSNumber numberWithBool:isChecked_];
}
*/
- (IBAction) checkboxTapped {
if (self.isChecked == NO) {
self.isChecked = YES;
// If I comment this out, the checked.png doesn't render
[self setImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateNormal];
self.selectedItem.inCart = [NSNumber numberWithBool:isChecked_];
// I commented this out because for some reason it prevents the checkbox from unchecking
//self.isChecked = [[selectedItem_ inCart] boolValue];
} else {
self.isChecked = NO;
// If I comment this out, once the checkbox is checked, it won't uncheck
[self setImage:[UIImage imageNamed:#"unchecked.png"] forState:UIControlStateNormal];
self.selectedItem.inCart = [NSNumber numberWithBool:isChecked_];
self.isChecked = [[selectedItem_ inCart] boolValue];
}
}
I left cellForRowAtIndexPath as #imaginaryboy suggested, except I used checkBox.isChecked = [[item inCart] boolValue]; as #westsider suggested. While this seems cleaner than what I was doing before, I'm not quite sure how to handle my original issue. I've been re-reading the docs, yet remain at a loss. Is there a way to check that inCart is actually getting its state changed? As for the checked cells, should I be caching them, or writing cells to a plist, or giving each cell its own unique identifier at creation (as I'm writing this, that seems like the way to go. Yes?)?
It occurs to me that if I was really successful in changing the state of inCart (which is a core data attribute), shouldn't its state be saved automatically when the checkbox gets checked, assuming that checkBox.isChecked = [[item inCart] boolValue]; works?
Firstly, as I commented on a little while ago, you're reusing cells but adding a new UILabel and Checkbox every time a cell is reused in addition to when it's first created.
To sort that out, something like the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UILabel *itemLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 0, 100, 40)];
itemLabel.tag = 1;
[cell.contentView addSubview:itemLabel];
Checkbox *checkbox = [[Checkbox alloc] initWithFrame:CGRectMake(10, 0, 70, 50)];
checkbox.tag = 2;
[cell.contentView addSubview:checkbox];
}
Item *item = [fetchedResultsController_ objectAtIndexPath:indexPath];
[self configureCell:cell withItem:item];
UILabel *itemLabel = (UILabel*)[cell viewWithTag:1];
itemLabel.text = item.itemName;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
Checkbox *checkbox = (Checkbox*)[cell viewWithTag:2];
checkbox.isChecked = YES or NO based on item.inCart??
return cell;
}
Though actually rather than setting the itemLabel.text and checkbox state here, perhaps the method configureCell:withItem: that you're calling could/should do that?
With respect to the issue you're having where the state isn't preserved between navigations, it may be simply that you're adding this new Checkbox to the cell every time and so it's appearing in whatever it's default checked/unchecked state is.
Also, you may want to try something like the following in Checkbox:
- (void)setIsChecked:(BOOL)isChecked {
if (isChecked_ = isChecked)
return;
[self setImage:[UIImage imageNamed:isChecked_?#"checked.png":#"unchecked.png"] forState:UIControlStateNormal];
self.selectedItem.inCart = [NSNumber numberWithBool:isChecked_];
}
- (IBAction) checkboxTapped {
if (self.isChecked == NO) {
self.isChecked = YES;
} else {
self.isChecked = NO;
}
}
EDIT: modified assigment of self.selectedItem.inCart as per #westsider's comment
You are going to need some code somewhere that actually sets the checkbox image based on the value of selectedItem.inCart. My guess is that inside ItemsVC you will want to implement -viewWillAppear: or -viewDidAppear: and iterate through your checkboxes, setting them as would be appropriate.
Without seeing more of your code, I can't suggest any more than this.