I have a UITableView that displays checkmarks when a row is selected. The problem is that when the table view scrolls multiple checkmarks are shown when only one was ever row selected. The problem arises as the table scrolls and the dequeue process occurs. Here's my cellForRowAtIndexPath: method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MainCell"];
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:CGRectZero];
cell.selectedBackgroundView.backgroundColor = [UIColor colorWithRed:204.0/255.0 green:56.0/255.0 blue:55.0/255.0 alpha:1];
}
// Get item from tableData
NSDictionary *item = (NSDictionary *)[displayItems objectAtIndex:indexPath.row];
cell.textLabel.text = [item objectForKey:#"key"];
[cell.textLabel setFont:[UIFont fontWithName: #"Asap-Bold" size: 14.0f]];
return cell;
}
and didSelect method:
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
selectedCityTableString = cell.textLabel.text;
cellAccessoryImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"icon-tick.png"]] ;
cellAccessoryNoneImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#""]] ;
if (cell.accessoryType==UITableViewCellAccessoryNone)
{
// cell.accessoryType=UITableViewCellAccessoryCheckmark;
cell.accessoryView = cellAccessoryImageView;
if (prev!=indexPath.row) {
cell=[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:prev inSection:0]];
//cell.accessoryType=UITableViewCellAccessoryNone;
cell.accessoryView = cellAccessoryNoneImageView;
prev=indexPath.row;
}
}
else{
// cell.accessoryType=UITableViewCellAccessoryNone;
cell.accessoryView = cellAccessoryNoneImageView;
}
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *mutCityStr = [[selectedCityTableString stringByReplacingOccurrencesOfString:#" " withString:#"+"] lowercaseString];
// NSString *mutCityStr = #"c";
[prefs setObject:mutCityStr forKey:#"selectedCityTableString"];
[prefs synchronize];
#ifdef DEBUG
NSLog(#"mutCityStr is %#",mutCityStr);
NSLog(#"selectedCityTableString is %#",selectedCityTableString);
NSLog(#"posting notification from TWO TABLES");
#endif
[[NSNotificationCenter defaultCenter] postNotificationName:#"TTSelectedList" object:selectedCountryTableString];
}
Supposing you have a property (attribute) called selectedRow use the combination of this methods:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
if (indexPath.row == self.selectedRow) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// If there is a cell selected deselect
if (self.selectedRow != NSNotFound) {
NSIndexPath *previousIndexPath = [NSIndexPath indexPathForRow:self.selectedAQIType inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:previousIndexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
}
// Select the touched cell
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.selectedRow = indexPath.row;
}
In your .h file
int selectedRow;
In your .m file
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// your other code for cell init,etc
int row = [indexPath row];
cell.accessoryType = (row == selectedRow) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
cell.textLabel.textColor= (row == selectedRow) ? [UIColor colorWithRed:242.0f/255.0f green:104.0f/255.0f blue:42.0f/255.0f alpha:1] : [UIColor blackColor] ;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectedRow = [indexPath row];
[tableView reloadData];
}
Hope this helps!!!
UITableView's delegate method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath reuses the cell based on the reuseidentifier. Hence you need to reset the entire cell contents to default.
In your case uncheck the cell's view before you return the cell.
To solve this problem, store your selected row indexes in one NSArray. (in didSelectRowAtIndexPath method)
And in cellForRowAtIndexPath method, check whether indexPath.row is available in that array then enable your checkmark, else disable.
Note: Maintain array for check-uncheck event
Hope this will help you.
Related
i am a beginner in xcode. I am creating a questionnaire type list with multiple rows in scroll. But when I select a row and scroll it doesn't retains its state and when I come back, it also loses its selection. So anyone please kindly let me know how to achieve that,i have tried something like this,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(val==1)
{
checkedArr=[[NSMutableArray alloc] init];
for (int i = 0; i<17; i++)
{
[checkedArr addObject:#"1"];
}
NSLog(#"Checked arr size %i",[checkedArr count]);
return 17;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%i",indexPath.row];
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil)
{
cell= [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:14.0];
}
cell.textLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:18.0];
UIView *selectionColor = [[UIView alloc] init];
selectionColor.backgroundColor = [UIColor colorWithRed:99/255.0f green:209/255.0f blue:248/255.0f alpha:1.0];
cell.selectedBackgroundView = selectionColor;
if([[checkedArr objectAtIndex:indexPath.row] isEqual:#"0"])
{
cell.accessoryView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tick.png"]];
NSLog(#"checkedArr 0000000");
}
else if ([[checkedArr objectAtIndex:indexPath.row] isEqual:#"1"])
{
cell.accessoryView=nil;
NSLog(#"checkedArr 111111");
}
cell.textLabel.frame=CGRectMake(75.0, 50.0, 150.0, 20.0);
cell.textLabel.text=[listArray objectAtIndex:indexPath.row];
NSLog(#"Checked arr size %i",[checkedArr count]);
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
cell=[questionTable cellForRowAtIndexPath:indexPath];
[checkedArr replaceObjectAtIndex:indexPath.row withObject:#"0"];
if([[checkedArr objectAtIndex:indexPath.row] isEqual:#"0"])
{
cell.accessoryView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tick.png"]];
NSLog(#"checkedArr 0000000");
}
else if ([[checkedArr objectAtIndex:indexPath.row] isEqual:#"1"])
{[questionTable deselectRowAtIndexPath:indexPath animated:YES];
cell.accessoryView=nil;
NSLog(#"checkedArr 111111");
}
NSLog(#"Val is %i",val);
NSLog(#"selected is %#",[listArray objectAtIndex:indexPath.row]);
// NSLog(#"Checked arr descripton %#",[checkedArr description]);
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryView = UITableViewCellAccessoryNone;
}
In my application i used same code for check mark as accessoryType,check this.
take it in .h file mutable array arSelectedRows;
- (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 setSelectionStyle:UITableViewCellSelectionStyleGray];
//Do anything you want for cell here
if([arSelectedRows containsObject:indexPath]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[arSelectedRows addObject:indexPath];
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[arSelectedRows removeObject:indexPath];
}
NSLog(#"arSelectedRows are :%#",arSelectedRows);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
EDIT
//if you want only single check mark
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[arSelectedRows removeAllObjects];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[arSelectedRows addObject:indexPath];
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[arSelectedRows removeObject:indexPath];
}
NSLog(#"arSelectedRows are:%#",arSelectedRows);
[self.tableview reloadData];//Reload your tableview here
}
it will help you.
First your cellForRowAtIndexPath method create new cell each time whenever you scroll up/down tableView, it is very bad for memory management.
Just remove [questionTable deselectRowAtIndexPath:indexPath animated:YES] in your cellForRowAtIndexPath method
I think you need to use this api below:-
- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition
If you are using dynamic cells, and updating your row with some kind of class variable like a NSArray, you might have set your variable to weak instead of strong.
I want to make a typical situation: when user selects any cell, it's accessoryType turns in checkmark. Only one cell's accessoryType can be checkmark. And then I wanna save in NSUserDefaults indexPath.row so my app will be able to know which cell user selected and make some changes in options. So I wrote this wrong code:
didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// checkedIndexPath is NSIndexPath
if(self.checkedIndexPath)
{
UITableViewCell* uncheckCell = [tableView
cellForRowAtIndexPath:self.checkedIndexPath];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.checkedIndexPath = indexPath;
[[NSUserDefaults standardUserDefaults]setObject:[NSNumber numberWithInt:self.checkedIndexPath.row]forKey:#"indexpathrow" ];
}
cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Part of code from cellForRowAtIndexPath
if(indexPath.row == [[[NSUserDefaults standardUserDefaults]objectForKey:#"indexpathrow"]intValue ])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
However, this code works badly. When you open the UITableView, there is an already selected cell in the table and when you press another there are two checkmarked cells...How can I improve my code or should I change it whole ? Any suggestions ?
Thanks !
Try this code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// checkedIndexPath is NSIndexPath
NSIndexPath *previousSelection = self.checkedIndexPath;
NSArray *array = nil;
if (nil != previousSelection) {
array = [NSArray arrayWithObjects:previousSelection, indexPath, nil];
} else {
array = [NSArray arrayWithObject:indexPath];
}
self.checkedIndexPath = indexPath;
[tableView reloadRowsAtIndexPaths:array withRowAnimation: UITableViewRowAnimationNone];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Part of code from cellForRowAtIndexPath
NSString *cellID = #"CellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (nil == cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
[cell autorelease];
}
// some code for initializing cell content
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if(self.checkedIndexPath != nil && indexPath.row == self.checkedIndexPath.row)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
I have a array of 8 items put in a table view.I am using the following code to set the check mark on tap of a row
[[tableView cellForRowAtIndexPath:indexPath]
setAccessoryType:UITableViewCellAccessoryCheckmark];
.But my problem is
1] whenever i tap my first row ,the fifth rows check mark also get showed up.
And
2] when i scroll the table view after checking a row , and return back , checked mark gets disappears.
How to get rid of these problem.
thanks in advance
here is the code
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
// find the cell being touched and update its checked/unchecked image
CellView *targetCustomCell = (CellView *)[tableView cellForRowAtIndexPath:indexPath];
[targetCustomCell checkAction:nil];
if ([arrData count]>0)
{
if ([arrData containsObject:[arrName objectAtIndex:indexPath.row]]) {
[arrData removeObject:[arrName objectAtIndex:indexPath.row]];
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryNone];
NSLog(#"data removed");
NSLog(#"arrData%#",arrData);
}
else {
[arrData addObject:[arrName objectAtIndex:indexPath.row]];
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
NSLog(#"data added");
NSLog(#"tableArray%#",arrData);
}
}
else {
[arrData addObject:[arrName objectAtIndex:indexPath.row]];
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
NSLog(#"data added");
NSLog(#"arrData%#",arrData);
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kCustomCellID = #"MyCellID";
CellView *cell = (CellView *)[tableView dequeueReusableCellWithIdentifier:kCustomCellID];
if (cell == nil)
{
cell = (CellView *)[[[CellView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCustomCellID] autorelease];
}
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.font = [UIFont boldSystemFontOfSize:13];
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.textAlignment = UITextAlignmentLeft;
cell.textLabel.text = [arrName objectAtIndex:indexPath.row];
return cell;
}
for your 1) problem you have provide some code
2) problem :
you need to remember your last selected row for that you need to store your last selected index number by :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
selectedIndex = indexPath.row;
[tableView reloadData];
}
and in your
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == selectedIndex)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
cell.accessoryType = UITableViewCellAccessoryNone;
return cell;
}
hope it helps you.
This
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
... modifies the "accessoryType" of every 6th cell INSTEAD of just the selected row. What am I missing?
Thanks
UPDATED: Here is the cell creation code ...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *TC = #"TC";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: TC];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:PlayerTableViewCell] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [NSString stringWithFormat:#"Person %d", row+1];
return cell;
}
MY SOLUTION based on the marked answer below is ...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// EVERY row gets its one Identifier
NSString *TC = [NSString stringWithFormat: #"TC%d", indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: TC];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TC] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [NSString stringWithFormat:#"Person %d", row+1];
return cell;
}
If there is a better way I'm all ears. Would be nice if we could just change the SPECIFIC Cell according to the NSIndexPath passed in someday (at least that seems a whole lot more intuitive to me).
I got it to work by using setting the accessory type in cellForRowAtIndexPath based on variable which keeps track of the selected row. Then in didSelectRowAtIndexPath i just deselect the row, update the variable, and reload the table.
CODE SAMPLE:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [NSString stringWithFormat:#"%d", indexPath.row];
if ([_cells indexOfObjectIdenticalTo:_selectedCell] == indexPath.row) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
_selectedCell = [_cells objectAtIndex:indexPath.row];
[tableView reloadData];
}
Yeah, just figured out. These are the same cells ( logs below are NSLog( #"%d %#", row, cell ) ).
2010-04-15 12:43:40.722 ...[37343:207] 0 <MyListCell: 0x124bee0; baseClass = UITableViewCell; frame = (0 0; 320 44); autoresize = RM+TM; layer = <CALayer: 0x124c3a0>>
2010-04-15 12:43:47.827 ...[37343:207] 10 <MyListCell: 0x124bee0; baseClass = UITableViewCell; frame = (0 31; 340 44); autoresize = W; layer = <CALayer: 0x124c3a0>>
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: PlayerTableViewCell];
dequeueReusableCellWithIdentifier uses already created cell, if the previous one is out of a screen.
So, you should avoid using "dequeueReusableCellWithIdentifier" - create a dictionary NSIndexPath -> UITableViewCell and use it instead of dequeueReusableCellWithIdentifier.
ADDED:
You can also check if the (rowNumber+1) exists in a winningNumbers array and replace accessory in a tableView:cellForRowAtIndexPath: method. This should work too
I simplified my code to test with, and still on the phone my memory usage keeps climbing to a point where the table slows way down.
Can someone tell me what I'm doing wrong here?
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 40;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"Cell";
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellID] autorelease];
}
UILabel *l=[[UILabel alloc] initWithFrame:CGRectMake(10,10,300,16)];
l.font=[UIFont boldSystemFontOfSize:15];
l.textColor=[UIColor whiteColor];
l.backgroundColor=[UIColor blackColor];
l.text=#"Just some randoom text here";
[cell.contentView addSubview:l];
[l release];
Oops. That code paste didn't work too well. Here's a straight paste:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 40;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"Cell";
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellID] autorelease];
}
UILabel *l=[[UILabel alloc] initWithFrame:CGRectMake(10,10,300,16)];
l.font=[UIFont boldSystemFontOfSize:15];
l.textColor=[UIColor whiteColor];
l.backgroundColor=[UIColor blackColor];
l.text=#"Just some randoom text here";
[cell.contentView addSubview:l];
[l release];
return cell;
}
You will want to follow a pattern like this:
#define kTagMyLabel 1
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"Cell1";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID];
UILabel * l;
if (cell == nil) {
// create the cell
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellID] autorelease];
// perform setup/functions that are common to all cells
l = [[[UILabel alloc] initWithFrame:CGRectMake(10,10,300,16)] autorelease];
l.font=[UIFont boldSystemFontOfSize:15];
l.textColor=[UIColor whiteColor];
l.backgroundColor=[UIColor blackColor];
l.tag = kTagMyLabel ;
[cell.contentView addSubview:l];
}
else
{
// find the label we previously added.
l = (UILabel*)[cell viewWithTag:kTagMyLabel];
}
// now set up the cell specific to this indexPath
l.text=#"Just some random text here";
return cell;
}
You're recycling UITableViewCell instances, but you're still creating a new UILabel instance for every row, and adding it to each and every cell. This is where the memory usage comes from. Try something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"Cell";
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellID] autorelease];
UILabel *l=[[UILabel alloc] initWithFrame:CGRectMake(10,10,300,16)];
l.font=[UIFont boldSystemFontOfSize:15];
l.textColor=[UIColor whiteColor];
l.backgroundColor=[UIColor blackColor];
l.text=#"Just some randoom text here";
[cell.contentView addSubview:l];
[l release];
}
return cell;
}
Since every UITableViewCell has its own standard UILabel (cell.textLabel), do you really need that extra label added to the contentView? If you need custom cells, you might want to consider subclassing UITableViewCell.