In my UITableView I am trying to display all the items in my plist but its not showing all the items. Actually it is showing most of it but the lower items are being repeated for some odd reason. I basically want to show all the keys in the plist with their respective values. Is the list too long to display? there's about 30 items.
First I tried to sort the keys and thought that was the problem, so then I didn't sort at all and I get the same problem, lower down the list the items get repeated and not showing the last 3 items. Is there a limit?
Below is some code, I've just modified to fit:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"PreferencesCell1";
static NSString *CellIdentifier2 = #"PreferencesCell2";
static NSString *CellIdentifier3 = #"PreferencesCell3";
UITableViewCell *cell;
NSArray *keys = [[[preferences objectAtIndex:indexPath.section] objectForKey:#"Rows"] allKeys];
NSString *prefName = [keys objectAtIndex:indexPath.row];
if (indexPath.section == 0 || indexPath.section == 2) {
if(indexPath.section == 0)
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
else if(indexPath.section == 2)
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil) {
if(indexPath.section == 0)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1] autorelease];
else if(indexPath.section == 2)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
CGRect labelRect = CGRectMake(10, 5, 300, 31);
UILabel *settingName = [[UILabel alloc] initWithFrame:labelRect];
settingName.font = [UIFont boldSystemFontOfSize:17.0];
settingName.backgroundColor = [UIColor clearColor];
settingName.text = prefName;
[cell.contentView addSubview: settingName];
[settingName release];
}
} else if(indexPath.section == 1) {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier3];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier3] autorelease];
CGRect labelRect = CGRectMake(10, 5, 300, 31);
UILabel *label = [[UILabel alloc] initWithFrame:labelRect];
label.font = [UIFont boldSystemFontOfSize:17.0];
label.backgroundColor = [UIColor clearColor];
label.text = prefName;
[cell.contentView addSubview: label];
}
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return cell;
}
What I've found is that if I don't use the labels and just go for the generic cell.textLabel.text approach then all the items are displayed correctly. However if I use the UILabel approach, the bottom items are not shown. I need to go this route as I'm adding other items in the Cell.
Working Code.
Initialization and creation of cell must be created first, then using that referenced cell remove from superview, then render the subviews. So reordering of the code from above.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"PreferencesCell1";
static NSString *CellIdentifier2 = #"PreferencesCell2";
static NSString *CellIdentifier3 = #"PreferencesCell3";
UITableViewCell *cell;
NSArray *keys = [[[preferences objectAtIndex:indexPath.section] objectForKey:#"Rows"] allKeys];
NSString *prefName = [keys objectAtIndex:indexPath.row];
// Create/Initialize Cell first
if (indexPath.section == 0 || indexPath.section == 2) {
if(indexPath.section == 0)
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
else if(indexPath.section == 2)
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil) {
if(indexPath.section == 0)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1] autorelease];
else if(indexPath.section == 2)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2] autorelease];
}
} else if(indexPath.section == 1) {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier3];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier3] autorelease];
}
}
// remove from superview
[cell.contentView.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
// render the subviews
if (indexPath.section == 0 || indexPath.section == 2) {
cell.accessoryType = UITableViewCellAccessoryNone;
CGRect labelRect = CGRectMake(10, 5, 300, 31);
UILabel *settingName = [[UILabel alloc] initWithFrame:labelRect];
settingName.font = [UIFont boldSystemFontOfSize:17.0];
settingName.backgroundColor = [UIColor clearColor];
settingName.text = prefName;
[cell.contentView addSubview: settingName];
[settingName release];
} else if(indexPath.section == 1) {
CGRect labelRect = CGRectMake(10, 5, 300, 31);
UILabel *label = [[UILabel alloc] initWithFrame:labelRect];
label.font = [UIFont boldSystemFontOfSize:17.0];
label.backgroundColor = [UIColor clearColor];
label.text = prefName;
[cell.contentView addSubview: label];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return cell;
}
It looks like cells are being reused and you are just adding new views to their existing contents. You need to reset the content, as described here: UITbleViewCell Class Reference. If you were just setting the cell's textLabel each time, setting a new value would suffice here, but if you are adding subviews you may need something more like [cell.contentView.subviews makeObjectsPerformSelector: #selector(removeFromSuperview)];
The Limit for a Tableview is the free RAM size.
Please post some Code. But i think that this could be a Problem with Cell caching.
Related
I am trying to hide the grey line (seperator) under two cells in my UITableView however I am having trouble.
I have a Grouped UITableView and this is my cellForRowAtIndexPath method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (indexPath.section == 0)
{
if (indexPath.row == 0) {
// Date
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"Date:";
cell.detailTextLabel.text = currentDateString;
} else if (indexPath.row == 1) {
// UIPicker
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.clipsToBounds = YES;
[cell.contentView addSubview:datePickerForCell];
}
} else if (indexPath.section == 1) {
if (indexPath.row == 0) {
// Order No.
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"Order No:";
cell.detailTextLabel.text = #"001-01989";
} else if (indexPath.row == 2) {
// Location
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"Completed:";
CGFloat optionalRightMargin = 10.0;
CGFloat optionalBottomMargin = 10.0;
completedByTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, cell.contentView.frame.size.width - 110 - optionalRightMargin, cell.contentView.frame.size.height - 10 - optionalBottomMargin)];
self.completedByTextField.delegate = self;
completedByTextField.textColor = [UIColor grayColor];
completedByTextField.tag = 2;
completedByTextField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
completedByTextField.textAlignment = NSTextAlignmentRight;
completedByTextField.placeholder = #"Name";
completedByTextField.text = completedByString;
[cell.contentView addSubview:completedByTextField];
} else if (indexPath.row == 3) {
// Hours Worked
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"Hours Worked:";
cell.detailTextLabel.text = #"4 hrs 26 min";
}
} else if (indexPath.section == 2) {
if (indexPath.row == 0) {
// Description
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"Description:";
} else if (indexPath.row == 1) {
// Description Textfield
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
[cell.contentView addSubview:descriptionTextView];
}
} else if (indexPath.section == 3) {
if (indexPath.row == 0) {
// Materials
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"Materials:";
}
}
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
return cell;
}
I would like to hide the separators under the
// Description Textfield Cell
and
// Materials Textfield Cell (this has not been written yet, its just I wanted to make clear that there will be two cells I want to do this two not just one as it may affect your answer I guess...)
I have read about using tableview.separatorcolor but this changes the color of every cells separator color in the TableView.
As far as I know its not possible to just hide cell separator for some cells. It will be applicable for complete table view.
However you can achieve this by adding a transparent or white image view on those cells which you want to hide the separator. Keep the Image view size a little bit larger than the row height. May be it should help.
Otherwise in general its not possible to just hide cell separator for some cells. If you make any changes in a particular separator, it will be reflected in all table view cell separators.
You can't trigger the separator to hide/unhide for specific cells for a UITableView. Rather, disable the cell separator altogether and add a custom separator to the cells you need. Add the following code to the cells you need to show a separator on:
UIView* separatorView = [[UIView alloc] initWithFrame:CGRectMake(0, cell.contentView.frame.size.height-1, cell.contentView.frame.size.width, 1)];
separatorView.backgroundColor = [UIColor lightGrayColor]; // set custom color here
[cell.contentView addSubview:separatorView];
You can use this line of code in your cellForRowAtIndexPath method-
tableView.separatorStyle=UITableViewCellSeparatorStyleNone;
you can hide the line by set tableview offset.
cell.separatorInset = UIEdgeInsetsMake(0.0, 45.0, 0.0, 0.0);
I'm trying to create a in app setting tableview, which requires different sections with different content. i first tried all the code outside (!cell), but that resulted in duplicate of the content on scroll, i've then found thread where it said i needed to put inside (!cell), but now it does not show any content. What am i doing wrong?
CellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
cell.backgroundColor = [UIColor colorWithRed:0.953 green:0.953 blue:0.965 alpha:1] ;
self.emailTextField.delegate = self;
self.cellName = [[UILabel alloc] initWithFrame:CGRectMake(20, 12, 42, 20)];
self.cellName.textColor = [UIColor colorWithRed:0.137 green:0.145 blue:0.157 alpha:1];
self.cellName.font = [UIFont fontWithName:#"HelveticaNeue" size:14];
[cell.contentView addSubview:self.cellName];
if (indexPath.section == 1) {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
self.cellName.text = [notArray objectAtIndex:indexPath.row];
if (indexPath.row == 0) {
self.acceptanceSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(251, 6, 31, 51)];
[cell.contentView addSubview:self.acceptanceSwitch];
} else if (indexPath.row == 1) {
self.messageSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(251, 6, 31, 51)];
[cell.contentView addSubview:self.messageSwitch];
} else if (indexPath.row == 2) {
self.likeSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(251, 6, 31, 51)];
[cell.contentView addSubview:self.likeSwitch];
}
} else if (indexPath.section == 0) {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
self.cellName.text = [accountArray objectAtIndex:indexPath.row];
if (indexPath.row == 0) {
self.nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 7, 190, 30)];
self.nameTextField.enabled = NO;
[cell.contentView addSubview:self.nameTextField];
} else if (indexPath.row == 1) {
self.emailTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 7, 190, 30)];
[cell.contentView addSubview:self.emailTextField];
[self.emailTextField setReturnKeyType:UIReturnKeyDone];
[self.emailTextField setKeyboardType:UIKeyboardTypeEmailAddress];
} else if (indexPath.row == 2) {
self.genderSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(251, 6, 31, 51)];
[cell.contentView addSubview:self.genderSwitch];
}
}
}
if (indexPath.section == 0) {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
self.cellName.text = [accountArray objectAtIndex:indexPath.row];
} else if (indexPath.section == 1) {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
self.cellName.text = [notArray objectAtIndex:indexPath.row];
} else if (indexPath.section == 2) {
self.cellName.text = [policyArray objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
} else if (indexPath.section == 3) {
self.cellName.text = [buttonsArray objectAtIndex:indexPath.row];
self.cellName.textAlignment = NSTextAlignmentCenter;
}
return cell;
}
Please try the following:
create a subclass of UITableViewCell with public properties (label, textfield). If you have different requirement for cells in different sections, maybe you should have different cell subclasses.
register these cell classes with the tableview in your view did load. e.g.
[self.tableView registerClass:[MySectionOneTableViewCell class] forCellReuseIdentifier:MySectionOneIdentifier];
[self.tableView registerClass:[MySectionTwoTableViewCell class] forCellReuseIdentifier:MySectionTwoIdentifier];
in the method below, just dequeue the cell after making a check for the section and set the properties.
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath )indexPath {
UITableViewCell cell;
if (indexPath.section == 0){
cell = (MySectionOneTableViewCell*)[tableView dequeueReusableCellWithIdentifier:MySectionOneIdentifier forIndexPath:indexPath;
cell.textLabel = #"foo";
}
return cell;
}
implement method, prepare for reuse in your custom uitableviewcell classes where you initialize all your labels and text fields. This method prepares the views of the cell for reuse.
e.g.
(void)prepareForReuse {
self.textLabel.text = #"";
}
As mentionned #rmaddy, you shouldn't mention the cell generation in your (!cell). The "code illustration" is the following:
- (void)viewDidLoad {
// This part wasn't included in any specific if/else condition dealing with cell properties (like section or row), not either being modified during the cell generation
self.emailTextField.delegate = self;
self.cellName = [[UILabel alloc] initWithFrame:CGRectMake(20, 12, 42, 20)];
self.cellName.textColor = [UIColor colorWithRed:0.137 green:0.145 blue:0.157 alpha:1];
self.cellName.font = [UIFont fontWithName:#"HelveticaNeue" size:14];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
// This part ensure you will initiate each cell with the correct identifier
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
cell.backgroundColor = [UIColor colorWithRed:0.953 green:0.953 blue:0.965 alpha:1] ;
}
[cell.contentView addSubview:self.cellName];
// You should check your code and commute the common condition together
if (indexPath.section == 0) {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
self.cellName.text = [accountArray objectAtIndex:indexPath.row];
// Be aware that your first section will contain only 3 rows
if (indexPath.row == 0) {
self.nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 7, 190, 30)];
self.nameTextField.enabled = NO;
[cell.contentView addSubview:self.nameTextField];
} else if (indexPath.row == 1) {
self.emailTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 7, 190, 30)];
[cell.contentView addSubview:self.emailTextField];
[self.emailTextField setReturnKeyType:UIReturnKeyDone];
[self.emailTextField setKeyboardType:UIKeyboardTypeEmailAddress];
} else if (indexPath.row == 2) {
self.genderSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(251, 6, 31, 51)];
[cell.contentView addSubview:self.genderSwitch];
}
} else if (indexPath.section == 1) {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
self.cellName.text = [notArray objectAtIndex:indexPath.row];
// Be aware that your second section will contain only 3 rows
if (indexPath.row == 0) {
self.acceptanceSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(251, 6, 31, 51)];
[cell.contentView addSubview:self.acceptanceSwitch];
} else if (indexPath.row == 1) {
self.messageSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(251, 6, 31, 51)];
[cell.contentView addSubview:self.messageSwitch];
} else if (indexPath.row == 2) {
self.likeSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(251, 6, 31, 51)];
[cell.contentView addSubview:self.likeSwitch];
}
} else if (indexPath.section == 2) {
// Here you are not adding any specific content to your section 2
self.cellName.text = [policyArray objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
} else if (indexPath.section == 3) {
// The same, your fourth section won't content any specific content
// You should add something like [cell addSubview:MyCustomView]
self.cellName.text = [buttonsArray objectAtIndex:indexPath.row];
self.cellName.textAlignment = NSTextAlignmentCenter;
}
return cell;
}
As I mentioned in my comments, if your local properties (cellName, nameTextField, genderSwitch, etc...) are well implemented, you will have only 6 row in all your table (3 in the first section and 3 in the second. Your third and fourth section will be empty since you didn't mention any subview within them.
Finally, since your code contained many confusion for me, it is possible I made some mistake in my rewriting, so feel free to correct me in this case.
Hopping it will help you in your work.
I set uitableview's cell as following
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
DetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[DetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.row == 0) {
cell.backgroundColor = [UIColor redColor];
UIImageView *bigphoto = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
bigphoto.image = [UIImage imageNamed:#"bigphoto.png"];
[cell addSubview:bigphoto];
}
else {
cell.backgroundColor = [UIColor blackColor];
cell.myphoto.image = [UIImage imageNamed:#"myphoto.png"];
cell.phototime.text = #"2014-03-01";
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
return 320;
}
return 220;
}
I want the first cell(indexPath.row = 0) is different from others, the first cell is set a bigphoto and its background color is red(with its UI Design), others are myphoto.png with black color background(with the UI Desigin of DetailCell), but the code runs with the wrong result,
the first cell(indexPath.row = 0) is right, but the indexPath.row = 3 or 6 or 9.. are the same as indexPath.row = 0, not like indexPath.row = 1 or 2 or 4...
so how can I fixed this? thanks
The cell is being reused, you should use different cell identifiers for cells with different representation. This should work:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier;
DetailCell *cell = nil;
if (indexPath.row == 0) {
cellIdentifier = #"Cell0";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[DetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.backgroundColor = [UIColor redColor];
UIImageView *bigphoto = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
bighoto.tag = 1;
[cell addSubview:bigphoto];
}
UIImageView *bigphoto = (UIImageView *)[cell viewWithTag:1];
bigphoto.image = [UIImage imageNamed:#"bigphoto.png"];
}
else {
cellIdentifier = #"Cell1";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[DetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.backgroundColor = [UIColor blackColor];
}
cell.myphoto.image = [UIImage imageNamed:#"myphoto.png"];
cell.phototime.text = #"2014-03-01";
}
return cell;
}
This is because the first cell is "reused." Since you are using these cells for two separate purposes, it would be much cleaner to have a prototype cell in the storyboard that you use for just the first row, and then otherwise reuse cells for the rest of the rows.
In your case best option is to use the static tabelViewCells. Please check on this link.
SOLUTION
Just read the answer of #Kjuly
Thanks alot
QUESTION
I used tableView with sections, each section has 4 rows, the first row it must show image from website which I used HJCache class to cache the image and avoid leaking/memory issues.
now, this code it works well and while I am scrolling fast it doesn't leak or make memory issue
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//UITableViewCell *cell=nil;
if (indexPath.row == 0) {
static NSString *CellIdentifier = #"Cell";
HJManagedImageV* mi;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
mi = [[HJManagedImageV alloc] initWithFrame:CGRectMake(0,0,cell.frame.size.width, 310)];
mi.tag = 999;
[cell addSubview:mi];
} else {
mi = (HJManagedImageV*)[cell viewWithTag:999];
[mi clear];
}
if (indexPath.row == 0) {
mi.image = [UIImage imageNamed:#"placeholder"];
mi.url = [NSURL URLWithString:[pictures objectAtIndex:indexPath.section]];
[objMan manage:mi];
UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(likeTappedDouble:)];
tapped.numberOfTapsRequired = 2;
[mi setUserInteractionEnabled:YES];
[mi addGestureRecognizer:tapped];
}
return cell;
}
}
But when I try to configure other rows it leaked and while scrolling the application make memory issue and be very slowly.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//UITableViewCell *cell=nil;
if (indexPath.row == 0) {
static NSString *CellIdentifier = #"Cell";
HJManagedImageV* mi;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
mi = [[HJManagedImageV alloc] initWithFrame:CGRectMake(0,0,cell.frame.size.width, 310)];
mi.tag = 999;
[cell addSubview:mi];
} else {
mi = (HJManagedImageV*)[cell viewWithTag:999];
[mi clear];
}
if (indexPath.row == 0) {
mi.image = [UIImage imageNamed:#"placeholder"];
mi.url = [NSURL URLWithString:[pictures objectAtIndex:indexPath.section]];
[objMan manage:mi];
UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(likeTappedDouble:)];
tapped.numberOfTapsRequired = 2;
[mi setUserInteractionEnabled:YES];
[mi addGestureRecognizer:tapped];
}
return cell;
}
static NSString *CellIdentifier = #"CellS";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
if (indexPath.row == 1) {
// configure row 1
}
if (indexPath.row == 2) {
// configure row 2
}
// etc for the others ..
return cell;
}
Where is the problem, Thanks..
UPDATE
This code doesn't work well, it add the subview in other row while scrolling
static NSString *CellIdentifier = #"CellS";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if (indexPath.row == 1) {
UIImage* likesimage = [UIImage imageNamed:#"likespic"];
CGRect frameimg = CGRectMake(7, 5, likesimage.size.width, likesimage.size.height);
likesbutton = [[UIButton alloc] initWithFrame:frameimg];
[likesbutton setBackgroundImage:likesimage forState:UIControlStateNormal];
likesbutton.backgroundColor = [UIColor clearColor];
[cell addSubview:likesbutton];
label3 = [[UILabel alloc] initWithFrame:CGRectMake(20, 2, 100, 20)];
label3.textColor = [UIColor colorWithRed:61.0/255.0 green:113.0/255.0 blue:154.0/255.0 alpha:1.0];
label3.backgroundColor = [UIColor clearColor];
label3.font = [UIFont fontWithName:#"Helvetica-Bold" size:12];
label3.adjustsFontSizeToFitWidth = YES;
[cell addSubview:label3];
}
}
For your other cells, you need to reuse the cell either:
static NSString *CellIdentifier = #"CellS";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
EDIT for Updated Question:
You need to know how "cell reusing" works. As for your updated code, it said only row 1 needs the subviews like image, right? So you need add it outside of the if (cell == nil){} snippet, like the code below:
static NSString *CellIdentifier = #"CellS";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
if (indexPath.row == 1) {
UIImage* likesimage = [UIImage imageNamed:#"likespic"];
CGRect frameimg = CGRectMake(7, 5, likesimage.size.width, likesimage.size.height);
likesbutton = [[UIButton alloc] initWithFrame:frameimg];
[likesbutton setBackgroundImage:likesimage forState:UIControlStateNormal];
likesbutton.backgroundColor = [UIColor clearColor];
[cell addSubview:likesbutton];
label3 = [[UILabel alloc] initWithFrame:CGRectMake(20, 2, 100, 20)];
label3.textColor = [UIColor colorWithRed:61.0/255.0 green:113.0/255.0 blue:154.0/255.0 alpha:1.0];
label3.backgroundColor = [UIColor clearColor];
label3.font = [UIFont fontWithName:#"Helvetica-Bold" size:12];
label3.adjustsFontSizeToFitWidth = YES;
[cell addSubview:label3];
}
Note: It's better to create a new cell instance like what you did for row 0, cause it's only need to be created once.
try this ...
man you are doing 2 mistakes here
not checking for dequeued cells.
after allocating the cell , you are not releasing it's memory.
i suggest this code for you .
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cellID";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
}
don't forget to autorelease cells .
remove all add subviews, then add new subviews
NSArray *subviews = [[NSArray alloc] initWithArray:cell.contentView.subviews];
for (UIView *subview in subviews) {
[subview removeFromSuperview];
}
When I scroll my tableview, the text gets all mashed up from the cells below. It's probably cause I recreate the UILabels every time cellForRow gets loaded, but I wouldn't know how to fix it:
(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger row = [indexPath row];
NSDictionary *currentRowDictionary = nil;
if (tableView == [[self searchDisplayController] searchResultsTableView])
currentRowDictionary = [[self searchResults] objectAtIndex:row];
else
currentRowDictionary = [[self tableData] objectAtIndex:row];
NSString *voornaam = [currentRowDictionary objectForKey:#"voornaam"];
NSString *achternaam = [currentRowDictionary objectForKey:#"achternaam"];
NSString *tussenvoegsel = [currentRowDictionary objectForKey:#"tussenvoegsel"];
voornaamLbl = [[[UILabel alloc] initWithFrame:CGRectMake(5, 10, 300, 40)] autorelease];
voornaamLbl.font = [UIFont fontWithName:#"TrebuchetMS-Bold" size:19];
voornaamLbl.text = voornaam;
voornaamLbl.numberOfLines = 0;
[voornaamLbl sizeToFit];
tussenvoegselLbl = [[[UILabel alloc] initWithFrame:CGRectMake(voornaamLbl.frame.size.width + 10, 10, 300, 40)] autorelease];
tussenvoegselLbl.text = tussenvoegsel;
tussenvoegselLbl.numberOfLines = 0;
[tussenvoegselLbl sizeToFit];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[cell.contentView addSubview:voornaamLbl];
if ([tussenvoegsel length] != 0)
{
[cell.contentView addSubview:tussenvoegselLbl];
achternaamLbl = [[[UILabel alloc] initWithFrame:CGRectMake(voornaamLbl.frame.size.width +
tussenvoegselLbl.frame.size.width + 15, 10, 300, 40)] autorelease];
} else {
achternaamLbl = [[[UILabel alloc] initWithFrame:CGRectMake(voornaamLbl.frame.size.width + 10, 10, 300, 40)] autorelease];
}
achternaamLbl.text = achternaam;
achternaamLbl.numberOfLines = 0;
[achternaamLbl sizeToFit];
[cell.contentView addSubview:achternaamLbl];
return cell;
}
You alloc and init new labels for everytime a cell is used. Cells are reused during scroll so your multiplying labels each time.
The best way is to create a seperate UITableViewCell subclass that creates the label on load, then in cellForRowAtIndexPath you use your new cell subclass and set the labels text
The end of this tutorial can help with cell subclasses http://www.raywenderlich.com/5138/beginning-storyboards-in-ios-5-part-1