Memory leaks showing up for tableview cells in the analyzer? - iphone

I have an application which is working fine.But i need to be memory leaks free.So i decided to build with analyzer,then i saw so many small small memory management issues.I sorted out almost everything except this.here my cell object is shown as a leaked object,but really i don't know where i was wrong footed.this is my cellforRowatIndexpath method .
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:EventCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:EventCellIdentifier];
UIImageView* img = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"cell_with_arrow.png"]];
[cell setBackgroundView:img];
[img release];
cell.textLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:13.0];
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap; // Pre-iOS6 use UILineBreakModeWordWrap
cell.textLabel.numberOfLines =0;
[cell.textLabel sizeToFit];
}
[[cell viewWithTag:12] removeFromSuperview];
[[cell viewWithTag:13] removeFromSuperview];
PTPusherEvent *event = [eventsReceived objectAtIndex:indexPath.row];
//cell.textLabel.text = event.name;
// cell.detailTextLabel.text = [event.data description];
NSDictionary *payload =event.data;
NSLog(#"%#",payload);
NSString *tes=[payload objectForKey:#"from"];
NSString *subtitle = [NSString stringWithString: #"From "];
subtitle = [subtitle stringByAppendingFormat:#"%#",tes];
cell.detailTextLabel.text = subtitle;
cell.textLabel.text = [payload objectForKey:#"message"];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
// [dateFormat setDateFormat:#"dd-MMM-YYYY HH:mm:ss"];
[dateFormat setDateFormat:#"dd-MMM-YYYY hh:mm a"];
[dateFormat setTimeZone:[NSTimeZone defaultTimeZone]];
NSDate *todaysdate=[NSDate date];
NSString *todaysdateString = [dateFormat stringFromDate:todaysdate];
[dateFormat release];
CGSize boundingSize = CGSizeMake(320, CGFLOAT_MAX);
CGSize requiredSize = [cell.textLabel.text sizeWithFont:cell.textLabel.font
constrainedToSize:boundingSize
lineBreakMode:UILineBreakModeWordWrap];
CGFloat requiredHeight = requiredSize.height;
MarqueeLabel *rateLabelOne = [[MarqueeLabel alloc] initWithFrame:CGRectMake(115, requiredHeight+15,155, 20) rate:50.0f andFadeLength:10.0f];
rateLabelOne.numberOfLines = 1;
rateLabelOne.marqueeType = MLContinuous;
rateLabelOne.opaque = NO;
rateLabelOne.enabled = YES;
rateLabelOne.shadowOffset = CGSizeMake(0.0, -1.0);
rateLabelOne.textAlignment = UITextAlignmentRight;
rateLabelOne.textColor = [UIColor redColor];
rateLabelOne.backgroundColor = [UIColor clearColor];
rateLabelOne.font = [UIFont fontWithName:#"Helvetica-Bold" size:12.000];
rateLabelOne.text = #"OFFline!cannot communicate now.....";
MarqueeLabel *rateLabelTwo = [[MarqueeLabel alloc] initWithFrame:CGRectMake(215, requiredHeight+15,100, 20) rate:50.0f andFadeLength:10.0f];
rateLabelTwo.marqueeType = MLContinuous;
rateLabelTwo.numberOfLines = 1;
rateLabelTwo.opaque = NO;
rateLabelTwo.enabled = YES;
rateLabelTwo.shadowOffset = CGSizeMake(0.0, -1.0);
rateLabelTwo.textAlignment = UITextAlignmentRight;
rateLabelTwo.textColor = [UIColor blueColor];
rateLabelTwo.backgroundColor = [UIColor clearColor];
rateLabelTwo.font = [UIFont fontWithName:#"Helvetica" size:12.000];
rateLabelTwo.text = todaysdateString;
if([chatstatus isEqualToString:#"online"])
{
rateLabelTwo.tag=12;
[cell addSubview:rateLabelTwo];
[rateLabelTwo release];
}
else
{
rateLabelOne.tag=13;
[cell addSubview:rateLabelOne];
[rateLabelOne release];
}
return cell;
}
Can anybody help me to find out where is that monster?

You need to put an autorelease as,
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:EventCellIdentifier] autorelease];
Otherwise it will be leaked.
Update:
As mentioned by AppleDelegate,
[rateLabelTwo release]; and [rateLabelOne release]; also need to be moved out of the if condition so that it will be released in both if and else cases. Analyzer will detect this also as a leak.

OK here's where the issue lies..
if([chatstatus isEqualToString:#"online"])
{
rateLabelTwo.tag=12;
[cell addSubview:rateLabelTwo];
[rateLabelTwo release];
}
else
{
rateLabelOne.tag=13;
[cell addSubview:rateLabelOne];
[rateLabelOne release];
}
In your code the rateLabelOne and rateLabelTow are released within an if loop.The static analyzer analyses it as a leak since it assumes there might be a case where the code doesnt run inside the if loop.Practically its not a leak.

cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:EventCellIdentifier]autoRelease];

Use this line:
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:EventCellIdentifier]autorelease];
This will remove your memory leak.

Related

Error reloading custom cell after changing data

I have a set up tableView which works fine.
As you can see below I want to add an image to my cell when the value for the object #"sent" changes to #"yes". After this is done i call [sendTable reloadData] but nothing happens to the tableView. Only when I restart the app my image is properly shown in the cell.
So obviously reloadData isn't doing anything here.
Can anybody figure out the problem?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
if (tableView == sendTable) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"savedItems.plist"];
savedItemsArray = [NSMutableArray arrayWithContentsOfFile:writableDBPath];
NSDictionary* item = [savedItemsArray objectAtIndex:indexPath.row];
NSString *temp = [NSString stringWithFormat:#"%#,%#", [[savedItemsArray valueForKey:#"name"]objectAtIndex:indexPath.row],
[[savedItemsArray valueForKey:#"message"]objectAtIndex:indexPath.row]];
UIView *background;
cell = [self.sendTable dequeueReusableCellWithIdentifier:temp];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:temp];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
cell.selectionStyle = UITableViewCellSelectionStyleGray;
background = [[UIView alloc] initWithFrame:cell.frame];
[cell addSubview:background];
[cell sendSubviewToBack:background];
}
if ([[item objectForKey:#"sent"] isEqualToString: #"no"]) {
UILabel *personLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, cell.frame.size.width-150, 20)];
personLabel.backgroundColor = [UIColor clearColor];
personLabel.text = [NSString stringWithFormat: #"%#",[item objectForKey:#"name"]];
personLabel.font = [UIFont boldSystemFontOfSize:17];
UILabel *personLabel2 = [[UILabel alloc]initWithFrame:CGRectMake(10, 30, cell.frame.size.width-150, 20)];
personLabel2.backgroundColor = [UIColor clearColor];
personLabel2.text = [NSString stringWithFormat: #"(%#)", [item objectForKey:#"number"]];
personLabel2.font = [UIFont systemFontOfSize:15];
UILabel *dateLabel = [[UILabel alloc]initWithFrame:CGRectMake(cell.frame.size.width-125, 10, 80, 40)];
dateLabel.backgroundColor = [UIColor clearColor];
dateLabel.text = [NSString stringWithFormat: #"%#\n%#",[item objectForKey:#"date"], [item objectForKey:#"time"]];
dateLabel.textColor = [UIColor darkGrayColor];
dateLabel.textAlignment = NSTextAlignmentRight;
dateLabel.font = [UIFont systemFontOfSize:13];
dateLabel.numberOfLines = 2;
UILabel *messageLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 60, cell.frame.size.width-50, 20)];
messageLabel.backgroundColor = [UIColor clearColor];
messageLabel.text = [NSString stringWithFormat: #"%#",[item objectForKey:#"message"]];
messageLabel.textColor = [UIColor lightGrayColor];
messageLabel.font = [UIFont systemFontOfSize:15];
[background addSubview:personLabel];
[background addSubview:personLabel2];
[background addSubview:dateLabel];
[background addSubview:messageLabel];
[cell addSubview:background];
}else{
UILabel *personLabel = [[UILabel alloc]initWithFrame:CGRectMake(40, 10, cell.frame.size.width-170, 20)];
personLabel.backgroundColor = [UIColor clearColor];
personLabel.text = [NSString stringWithFormat: #"%#",[item objectForKey:#"name"]];
personLabel.font = [UIFont boldSystemFontOfSize:17];
UILabel *personLabel2 = [[UILabel alloc]initWithFrame:CGRectMake(40, 30, cell.frame.size.width-170, 20)];
personLabel2.backgroundColor = [UIColor clearColor];
personLabel2.text = [NSString stringWithFormat: #"(%#)", [item objectForKey:#"number"]];
personLabel2.font = [UIFont systemFontOfSize:15];
UILabel *dateLabel = [[UILabel alloc]initWithFrame:CGRectMake(cell.frame.size.width-125, 10, 80, 40)];
dateLabel.backgroundColor = [UIColor clearColor];
dateLabel.text = [NSString stringWithFormat: #"%#\n%#",[item objectForKey:#"date"], [item objectForKey:#"time"]];
dateLabel.textColor = [UIColor darkGrayColor];
dateLabel.textAlignment = NSTextAlignmentRight;
dateLabel.font = [UIFont systemFontOfSize:13];
dateLabel.numberOfLines = 2;
UILabel *messageLabel = [[UILabel alloc]initWithFrame:CGRectMake(40, 60, cell.frame.size.width-80, 20)];
messageLabel.backgroundColor = [UIColor clearColor];
messageLabel.text = [NSString stringWithFormat: #"%#",[item objectForKey:#"message"]];
messageLabel.textColor = [UIColor lightGrayColor];
messageLabel.font = [UIFont systemFontOfSize:15];
UIImage *checkmarkImage = [UIImage imageNamed:#"done.png"];
UIImageView *checkmark = [[UIImageView alloc] initWithImage:checkmarkImage];
[checkmark setFrame:CGRectMake(10, 35, 20, 20)];
[background addSubview:personLabel];
[background addSubview:personLabel2];
[background addSubview:dateLabel];
[background addSubview:messageLabel];
[background addSubview:checkmark];
[cell addSubview:background];
}
}
return cell;
}
Thanks a lot!
As you are adding several UILabel and UIView to a cell,i think u should customize your own UITableViewCell.
Try to create a class subclassing UITableviewCell, and add subview in the implement.
Hope my answer is helpful

UITableView Showing 2 Cells For Every Item

My tableview parses a calendar RSS Feed. I set up the cell to have a blank calendar icon as the image for every cell, and add subviews for the month and day, which it detects using NSDate from the RSS itself. However, for some reason, it shows 2 cells for every event, and I cannot figure out why. Here is the code for the cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MM"];
NSString *monthfromdate = [formatter stringFromDate:entry.articleDate];
NSLog(#"%#", monthfromdate);
[formatter release];
NSDateFormatter *formatter2 = [[NSDateFormatter alloc] init];
[formatter2 setDateFormat:#"dd"];
NSString *datefromdate = [formatter2 stringFromDate:entry.articleDate];
NSLog(#"%#", datefromdate);
[formatter2 release];
if ([monthfromdate isEqualToString:#"01"]) {
self.currentmonth = #"January";
}
if ([monthfromdate isEqualToString:#"02"]) {
self.currentmonth = #"February";
}
if ([monthfromdate isEqualToString:#"03"]) {
self.currentmonth = #"March";
}
if ([monthfromdate isEqualToString:#"04"]) {
self.currentmonth = #"April";
}
if ([monthfromdate isEqualToString:#"05"]) {
self.currentmonth = #"May";
}
if ([monthfromdate isEqualToString:#"06"]) {
self.currentmonth = #"June";
}
if ([monthfromdate isEqualToString:#"07"]) {
self.currentmonth = #"July";
}
if ([monthfromdate isEqualToString:#"08"]) {
self.currentmonth = #"August";
}
if ([monthfromdate isEqualToString:#"09"]) {
self.currentmonth = #"September";
}
if ([monthfromdate isEqualToString:#"10"]) {
self.currentmonth = #"October";
}
if ([monthfromdate isEqualToString:#"11"]) {
self.currentmonth = #"November";
}
if ([monthfromdate isEqualToString:#"12"]) {
self.currentmonth = #"December";
}
NSString *currentday = datefromdate;
NSString *articleDateString = [dateFormatter stringFromDate:entry.articleDate];
UIFont *cellFont = [UIFont fontWithName:#"ArialRoundedMTBold" size:15];
UIFont *cellFont2 = [UIFont fontWithName:#"ArialRoundedMTBold" size:12];
UIFont *cellFont3 = [UIFont fontWithName:#"ArialRoundedMTBold" size:9];
UIFont *cellFont4 = [UIFont fontWithName:#"ArialRoundedMTBold" size:18];
UILabel *month = [[UILabel alloc] initWithFrame:CGRectMake(8, 10, 53, 21)];
month.font = cellFont3;
month.text = currentmonth;
month.textAlignment = UITextAlignmentCenter;
month.backgroundColor = [UIColor clearColor];
UILabel *date = [[UILabel alloc] initWithFrame:CGRectMake(11, 21, 50, 45)];
date.font = cellFont4;
date.text = currentday;
date.textAlignment = UITextAlignmentCenter;
date.backgroundColor = [UIColor clearColor];
UIImageView *alternate = [[UIImageView alloc] initWithFrame:CGRectMake(1,1,69,69)];
alternate.image = [UIImage imageNamed:#"calendar1.png"];
alternate.contentMode = UIViewContentModeScaleAspectFit;
UILabel *alternatelabel = [[UILabel alloc] initWithFrame:CGRectMake(82,0,228,53)];
alternatelabel.backgroundColor = [UIColor clearColor];
CALayer * l = [alternate layer];
[l setMasksToBounds:YES];
UILabel *detailLabel = [[UILabel alloc] initWithFrame:CGRectMake(82, 20, 228, 53)];
detailLabel.backgroundColor = [UIColor clearColor];
detailLabel.text = [NSString stringWithFormat:#"%# - %#", articleDateString, entry.blogTitle];
detailLabel.textColor = [UIColor grayColor];
detailLabel.font = cellFont2;
alternatelabel.font = cellFont;
alternatelabel.text = entry.articleTitle;
[cell.contentView addSubview:alternate];
[cell.contentView addSubview:alternatelabel];
[cell.contentView addSubview:detailLabel];
[cell.contentView addSubview:month];
[cell.contentView addSubview:date];
[detailLabel release];
[alternatelabel release];
[alternate release];
}
return cell;
}
You are wrong using cell reusing mechanism. Use this template
#define TAG_MONTH 1001
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
// any other views can be added to cell here
UILabel *month = [[UILabel alloc] initWithFrame:CGRectMake(8, 10, 53, 21)];
month.font = cellFont3;
month.textAlignment = UITextAlignmentCenter;
month.backgroundColor = [UIColor clearColor];
month.tag = TAG_MONTH;
}
// here you should fill all fields of cell with "entry" or make it empty
NSString currentmonth = #"something";
UILabel *month = [cell.contentView viewWithTag:TAG_MONTH];
month.text = currentmonth;
return cell;
}
Other moments :
you shouldn't init formatter in loop, init it once.
Exctract it into new method
if ([monthfromdate isEqualToString:#"01"]) {
self.currentmonth = #"January";
}
and optimize, it can be simpler
Check the number this method is returning, may be its returning 2
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

UITableView custom cells always change there content - must stop it

i have a UITableView with custom cells (code below) that load the data from NSDictionary (the NSDictionary loads there data from NSArray objectatIndexPath:indexpath.row.
Now, i have a DidSelectRow functions that works in the same way (NSArray -> NSDictionary -> Cell data).
the problem is that when im scrolling my table its change my cells contant.
i must have my cells always reload that same order. and i must stop this reloading data when scrolling.
This is the code im using to load my table view and load data to table view cells and my didSelectRow: Please help, i dont have time for this problem...
RequestArray = [jsonDictionary objectForKey:#"Content"];
RequestTable = [[UITableView alloc]initWithFrame:CGRectMake(0, 84, 320, 326)];
RequestTable.backgroundColor = [UIColor colorWithRed:(234/255.f) green:(234/255.f) blue:(234/255.f) alpha:1];
RequestTable.dataSource=self;
RequestTable.delegate=self;
RequestTable.rowHeight = 77;
[self.view addSubview:RequestTable];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier];
NSDictionary *object = [RequestArray objectAtIndex:indexPath.row];
NSString *Category = [object valueForKey:#"Category"];
NSString *ItemDescription = [object valueForKey:#"ItemDescription"];
NSString *ItemName = [object valueForKey:#"ItemName"];
NSString *Date = [object valueForKey:#"Date"];
NSString *ExpiresDate = [object valueForKey:#"ExpiresDate"];
BOOL isRead = [[object valueForKey:#"IsRead"]boolValue];
/// add time label to cell
NSTimeInterval TIMEinterval = [Date intValue];
NSDate* TIMEDate = [NSDate dateWithTimeIntervalSince1970:TIMEinterval];
NSDateFormatter* df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"HH:mm"];
[df setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:2]]; //+0000
NSString* dateStrig = [df stringFromDate:TIMEDate];
UILabel *RequestTime = [[UILabel alloc]initWithFrame:CGRectMake(268, 8, 33, 16)];
[RequestTime setTextAlignment:UITextAlignmentRight];
RequestTime.backgroundColor = [UIColor clearColor];
RequestTime.textColor = [UIColor blackColor];
[RequestTime setFont:[UIFont systemFontOfSize:12]];
RequestTime.text = dateStrig;
[cell addSubview:RequestTime];
/// add experation label to cell
NSTimeInterval EXPTIMEinterval = [ExpiresDate intValue];
NSDate* EXPDate = [NSDate dateWithTimeIntervalSince1970:EXPTIMEinterval];
NSTimeInterval secondsBetween = [EXPDate timeIntervalSinceDate:TIMEDate];
int numberOfHours = secondsBetween / 3600;
UILabel *ExperationTime = [[UILabel alloc]initWithFrame:CGRectMake(152, 24, 150, 15)];
ExperationTime.backgroundColor = [UIColor clearColor];
[ExperationTime setTextAlignment:UITextAlignmentRight];
ExperationTime.textColor = [UIColor colorWithRed:(255/255.f) green:(103/255.f) blue:(18/255.f) alpha:1];
[ExperationTime setFont:[UIFont systemFontOfSize:14]];
if (numberOfHours>24){
numberOfHours = numberOfHours/24;
ExperationTime.text = [NSString stringWithFormat:#"המוצר דרוש תוך %d ימים",numberOfHours];
}else{
ExperationTime.text = [NSString stringWithFormat:#"המוצר דרוש תוך %d שעות",numberOfHours];
}
[cell addSubview:ExperationTime];
// add item category to cell
UILabel *itamCategory = [[UILabel alloc]initWithFrame:CGRectMake(143 , 5, 120, 21)];
itamCategory.backgroundColor = [UIColor clearColor];
[itamCategory setTextAlignment:UITextAlignmentRight];
itamCategory.textColor = [UIColor colorWithRed:(0/255.f) green:(177/255.f) blue:(233/255.f) alpha:1];
[itamCategory setFont:[UIFont boldSystemFontOfSize:17]];
itamCategory.text = Category;
[cell addSubview:itamCategory];
// add item Name to cell
UILabel *itamName = [[UILabel alloc]initWithFrame:CGRectMake(98, 39, 203, 21)];
itamName.backgroundColor = [UIColor clearColor];
[itamName setTextAlignment:UITextAlignmentRight];
itamName.textColor = [UIColor blackColor];
[itamName setFont:[UIFont boldSystemFontOfSize:17]];
itamName.text = ItemName;
[cell addSubview:itamName];
// add item Description to cell
UILabel *Description = [[UILabel alloc]initWithFrame:CGRectMake(98, 62, 203, 10)];
Description.backgroundColor = [UIColor clearColor];
[Description setTextAlignment:UITextAlignmentRight];
Description.textColor = [UIColor blackColor];
[Description setFont:[UIFont systemFontOfSize:13]];
Description.text =ItemDescription;
[cell addSubview:Description];
//add sendOffer button
UIButton *callSeller = [UIButton buttonWithType:UIButtonTypeCustom];
callSeller.frame = CGRectMake(25, 8, 54, 45);
[callSeller setTag:indexPath.row];
[callSeller setBackgroundImage:[UIImage imageNamed:#"makeOfferTable.png"] forState:UIControlStateNormal];
[callSeller setBackgroundImage:[UIImage imageNamed:#"makeOfferTable.png"] forState:UIControlStateHighlighted];
[callSeller addTarget:self action:#selector(makeaOffer:) forControlEvents:UIControlEventAllEvents];
[cell addSubview:callSeller];
UIView *myBackView = [[UIView alloc] initWithFrame:cell.frame];
myBackView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"highlightCellBG.png"]];
cell.selectedBackgroundView = myBackView;
cell.backgroundColor = [UIColor lightGrayColor];
//add newOffer sign (if new)
if (!isRead){
UIImageView *newIndocator = [[UIImageView alloc]initWithFrame:CGRectMake(295, 0, 25, 25)];
newIndocator.image = [UIImage imageNamed:#"newOfferIndicator.png"];
[newIndocator setContentMode:UIViewContentModeScaleToFill];
[cell addSubview:newIndocator];
}
}
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *object = [RequestArray objectAtIndex:indexPath.row];
NSLog(#"indePath.row = %d",indexPath.row);
Seller_RequestDetailsViewController *infoView = [[Seller_RequestDetailsViewController alloc]initWithNibName:#"Seller_RequestDetailsViewController" bundle:nil];
NSString *OfferDate = [object valueForKey:#"Date"];
NSTimeInterval TIMEinterval = [OfferDate intValue];
NSDate* TIMEDate = [NSDate dateWithTimeIntervalSince1970:TIMEinterval];
NSDateFormatter* df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"DD/MM/yyyy"];
[df setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:2]]; //+0000
infoView.date = [df stringFromDate:TIMEDate];
infoView.itemName = [object valueForKey:#"ItemName"];
infoView.modalName = [object valueForKey:#"ItemDegem"];
infoView.buyerID = [NSString stringWithFormat:#"%#",[object valueForKey:#"BuyerUserID"]];
infoView.city = [object valueForKey:#"Region"];
infoView.Offerdescription = [object valueForKey:#"ItemDescription"];
BOOL isRead = [[object valueForKey:#"IsRead"]boolValue];
infoView.modalTransitionStyle = UIModalTransitionStylePartialCurl;
[self presentModalViewController:infoView animated:YES];
if (!isRead){
[self markOfferAsRead:[NSString stringWithFormat:#"%#",[object valueForKey:#"ItemID"]]];
}
}
I am not sure I understand your problem completely but I do see an error in the way you build the cells. After dequeueing the cell, you should only init the cell if it's nil NOT init and build the cell.
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier];
}
// Now build the cell.
If you don't rebuild the cell every time, it will just reuse the cell that was originally built.
your problem is that everything is with in this:
if(cell == nil) {
//Your Code
}
What is happening is the tableview reuses cells. You are only changing the content if(cell == nil).
What you need is to only create a new cell in side if(cell == nil)
and move the rest of your code out of that if statement

How can I search data from tableview cell?

I have an UITableview controller which representing fetched XML data. For representing these data I used five UILabel. Now I have to add a searchbar at the top of the UITableview. So programmatically I have added a searchbar.
Now I have used searching theorem for search data from the UITableview. But It is not working. I can search data from UItableview when only one text in the UItableviewcell without any UIlabel or something else but in my UItableviewcell cell are taking five UILabel that's why it's becoming tough for me to search data from the UItableviewcell. For understanding I am attaching my code how I am representing my XML data in tableview cell.
This is my XML data representation in UITableviewCell...
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:15.0];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"arrow.png"]];
cell.accessoryView = imageView;
cell.accessoryType = UITableViewCellSelectionStyleNone;
tableView.separatorColor = [UIColor clearColor];
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
cellView = [[[UIView alloc] initWithFrame:CGRectMake(5,8,290, 120)] autorelease];
cellView.backgroundColor = [UIColor clearColor];
cellView.tag =10;
[cell.contentView addSubview:cellView];
imgView = [[UIImageView alloc] initWithFrame:CGRectMake(2, 40, 48, 48)];
imgView.image = [UIImage imageNamed:#"productbox.png"];
imgView.layer.borderColor = [UIColor blackColor].CGColor;
imgView.layer.borderWidth = 2.0;
imgView.tag = 5;
[cellView addSubview:imgView];
CGRect idLabelRect = CGRectMake(65, 0, 190, 18);
idLabel = [[[UILabel alloc] initWithFrame:idLabelRect] autorelease];
idLabel.textAlignment = UITextAlignmentLeft;
idLabel.textColor = [UIColor blackColor];
idLabel.font = [UIFont systemFontOfSize:12];
idLabel.backgroundColor = [UIColor clearColor];
idLabel.layer.borderColor = [UIColor grayColor].CGColor;
idLabel.tag = 0;
CGRect statusRect = CGRectMake(65, 22, 190, 22);
statusLabel = [[[UILabel alloc] initWithFrame:statusRect] autorelease];
statusLabel.textAlignment = UITextAlignmentLeft;
statusLabel.textColor = [UIColor blackColor];
statusLabel.font = [UIFont systemFontOfSize:12];
statusLabel.backgroundColor = [UIColor clearColor];
statusLabel.layer.borderColor = [UIColor grayColor].CGColor;
statusLabel.tag = 1;
CGRect orderDateRect = CGRectMake(65, 48, 190, 22);
orderDate = [[[UILabel alloc] initWithFrame:orderDateRect] autorelease];
orderDate.textAlignment = UITextAlignmentLeft;
orderDate.textColor = [UIColor blackColor];
orderDate.font = [UIFont systemFontOfSize:12];
orderDate.backgroundColor = [UIColor clearColor];
orderDate.layer.borderColor = [UIColor grayColor].CGColor;
orderDate.tag = 2;
CGRect byRect = CGRectMake(65, 75, 190, 22);
byLabel = [[[UILabel alloc] initWithFrame:byRect] autorelease];
byLabel.textAlignment = UITextAlignmentLeft;
byLabel.textColor = [UIColor blackColor];
byLabel.font = [UIFont systemFontOfSize:12];
byLabel.backgroundColor = [UIColor clearColor];
byLabel.layer.borderColor = [UIColor grayColor].CGColor;
byLabel.tag = 3;
CGRect totalRect = CGRectMake(65, 98, 190, 22);
totalLabel = [[[UILabel alloc] initWithFrame:totalRect] autorelease];
totalLabel.textAlignment = UITextAlignmentLeft;
totalLabel.textColor = [UIColor blackColor];
totalLabel.font = [UIFont systemFontOfSize:12];
totalLabel.backgroundColor = [UIColor clearColor];
totalLabel.layer.borderColor = [UIColor grayColor].CGColor;
totalLabel.tag = 4;
[cellView addSubview:idLabel];
[cellView addSubview:statusLabel];
[cellView addSubview:orderDate];
[cellView addSubview:byLabel];
[cellView addSubview:totalLabel];
}
if(searching == YES){
//[cell setText:[tableData objectAtIndex:indexPath.row]];
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
}
else{
cellView = (UIView *)[cell.contentView viewWithTag:10];
idLabel = (UILabel *)[cellView viewWithTag:0];
statusLabel = (UILabel *)[cellView viewWithTag:1];
orderDate = (UILabel *)[cellView viewWithTag:2];
byLabel = (UILabel *)[cellView viewWithTag:3];
totalLabel = (UILabel *)[cellView viewWithTag:4];
imgView = (UIImageView *)[cellView viewWithTag:5];
if(pendingOrder == NO && todaysOrder == NO){
idLabel.text = [NSString stringWithFormat:#"Order Id: %#",[[records objectAtIndex:indexPath.section] objectAtIndex:0]];
statusLabel.text = [NSString stringWithFormat:#"Status: %#",[[records objectAtIndex:indexPath.section] objectAtIndex:1]];
orderDate.text = [NSString stringWithFormat:#"Date: %#",[[records objectAtIndex:indexPath.section] objectAtIndex:2]];
byLabel.text =[NSString stringWithFormat:#"By: %#",[[records objectAtIndex:indexPath.section] objectAtIndex:3]];
totalLabel.text =[NSString stringWithFormat:#"Total: %#",[[records objectAtIndex:indexPath.section] objectAtIndex:4]];
}
else if(pendingOrder == YES && todaysOrder == NO){
idLabel.text = [NSString stringWithFormat:#"Order Id: %#",[[pendingRecords objectAtIndex:indexPath.section] objectAtIndex:0]];
statusLabel.text = [NSString stringWithFormat:#"Status: %#",[[pendingRecords objectAtIndex:indexPath.section] objectAtIndex:1]];
orderDate.text = [NSString stringWithFormat:#"Date: %#",[[pendingRecords objectAtIndex:indexPath.section] objectAtIndex:2]];
byLabel.text =[NSString stringWithFormat:#"By: %#",[[pendingRecords objectAtIndex:indexPath.section] objectAtIndex:3]];
totalLabel.text =[NSString stringWithFormat:#"Total: %#",[[pendingRecords objectAtIndex:indexPath.section] objectAtIndex:4]];
}
}
return cell;
}
And this searching Delegate.....
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
searching = YES;
// only show the status bar’s cancel button while in edit mode
sBar.showsCancelButton = YES;
sBar.autocorrectionType = UITextAutocorrectionTypeNo;
// flush the previous search content
[tableData removeAllObjects];
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{
searching = NO;
sBar.showsCancelButton = NO;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
[tableData removeAllObjects];// remove all data that belongs to previous search
if([searchText isEqualToString:#""] && searchText==nil){
[tableview reloadData];
return;
}
NSInteger counter = 0;
for(NSString *name in dataSource)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSRange r = [name rangeOfString:searchText];
if(r.location != NSNotFound)
{
if(r.location== 0)//that is we are checking only the start of the names.
{
[tableData addObject:name];
}
}
counter++;
[pool release];
}
[tableview reloadData];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
// if a valid search was entered but the user wanted to cancel, bring back the main list content
[tableData removeAllObjects];
searching = NO;
[tableData addObjectsFromArray:dataSource];
#try{
searching = NO;
[tableview reloadData];
}
#catch(NSException *e){
}
[sBar resignFirstResponder];
sBar.text = #"";
}
// called when Search (in our case “Done”) button pressed
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[sBar resignFirstResponder];
}
For more help to understand i am also attaching my viewDidLoad....
//Add the search bar
sBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0,0,320,50)];
sBar.delegate = self;
searching = NO;
[self.view addSubview:sBar];
tableview.dataSource = self;
tableview.delegate = self;
//initialize the two arrays; datasource will be initialized and populated by appDelegate
searchData = [[NSMutableArray alloc] init];
tableData = [[NSMutableArray alloc] init];
[tableData addObjectsFromArray:dataSource];//on launch it should display all the records
Edit
This is my edited portion of numberOfSectionsInTableView and numberOfRowsInSection...
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if(searching == YES){
searching = NO;
sectionCount = [tableData count];
}
else {
if(pendingOrder == NO && todaysOrder == NO){
sectionCount = [records count];
NSLog(#"section cout: %d",sectionCount);
}
else if(pendingOrder == YES && todaysOrder == NO){
//Total pending order counting
sectionCount = [pendingRecords count];
NSLog(#"section cout for pending: %d",sectionCount);
}
else if(pendingOrder == NO && todaysOrder == YES){
NSLog(#"todays order number counting");
}
}
return sectionCount;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
Try this:-
copylistofItem is NSMutableArray copying data that matched with search bar criteria.
- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar {
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
int i=0
for (NSString *str in [records objectAtIndex:indexPath.i] objectAtIndex:0])
{
[searchArray addObject:str];
i++;
}
for (NSString *sTemp in searchArray)
{
NSString *txtToSearch =[[NSString alloc] initWithString:[sTemp substringWithRange:NSMakeRange(0,[searchText length])]];
if([[txtToSearch lowercaseString] isEqualToString:[searchText lowercaseString]])
{
[copyListOfItems addObject:sTemp];
}
}
[searchArray release];
searchArray = nil;
}
Also we want to know what you have written in your numberOfSections tableView Delegate.

iPhone: how to dealloc custom cell labels

hi i am working on UITableView custom cell for twitter, for each cell i am adding UIImageView(userPhoto), UILabel(name), UILabel(tweet), UILabel(Data), This i have to dealloc all elements,
please go through the attached Image of INSTRUMENT TOOL alloc screen shot
when i run the Instrument tool, it showing some are not dealloc, how to dealloc,
this is my code
//Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if(!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewStyleGrouped reuseIdentifier:nil];
//cell.selectionStyle = UITableViewCellSelectionStyleNone;
UILabel *name = [[UILabel alloc]initWithFrame:CGRectMake(72,3,242,15)] ;
name.text = (NSString*)[(Tweet*)[tweetArray objectAtIndex:indexPath.row] userName];
[name setFont:[UIFont fontWithName:#"Helvetica" size:13]];
name.textColor=[UIColor colorWithRed:250 green:250 blue:210 alpha:0.5];
[name setBackgroundColor:[UIColor clearColor]];
UILabel *date = [[[UILabel alloc]initWithFrame:CGRectMake(200,3,130,15)] autorelease];
date.text = (NSString*)[(Tweet*)[tweetArray objectAtIndex:indexPath.row] created_at];
[date setFont:[UIFont fontWithName:#"Helvetica" size:12]];
date.textColor=[UIColor colorWithRed:250 green:250 blue:210 alpha:0.5];
[date setBackgroundColor:[UIColor clearColor]];
UILabel * tweetLabel = [[UILabel alloc]initWithFrame:CGRectMake(72,20,242,60)] ;
tweetLabel.text = (NSString*)[(Tweet*)[tweetArray objectAtIndex:indexPath.row] tweet];
tweetLabel.numberOfLines = 3;
tweetLabel.textColor=[UIColor colorWithRed:252 green:148 blue:31 alpha:1];
[tweetLabel setFont:[UIFont fontWithName:#"Helvetica" size:12]];
[tweetLabel setBackgroundColor:[UIColor clearColor]];
UIImageView *myImage = [[UIImageView alloc]initWithFrame:CGRectMake(6,10,58,60)] ;
NSURL *url = [NSURL URLWithString:[(Tweet*)[tweetArray objectAtIndex:indexPath.row] image_url]];
NSData *data = [NSData dataWithContentsOfURL:url];
[myImage setImage: [UIImage imageWithData:data]];
[cell.contentView addSubview:myImage];
[cell.contentView addSubview:tweetLabel];
[cell.contentView addSubview:name];
[cell.contentView addSubview:date];
[myTweetActivityIndicator stopAnimating];
[myTweetActivityIndicator setHidesWhenStopped:YES];
return cell;
}
please guide me
Thank you
You can use
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewStyleGrouped reuseIdentifier:nil] autorelease];
For other labels, you can probably use
[date release]; [tweetLabel release]; [name release]; [myImage release];
You'll have to send a release message to all the objects that you have allocated using init/alloc (name, date, tweetLabel, myImage) as soon as you're finished with them (for example, after addSubview). Note that according to the documentation, the view is retained by the receiver.
try using
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
[myImage setImage: [UIImage imageWithData:data]];
[data release];
data = nil;
In this case, we are manually releasing the memory allocated. I hope, this works