Cell text overlapping on scrolling - ios

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

Related

The tableview row cannot be load correctly

The UITableView row cannot be loaded after row 13. The data reload from 0 again.
i found out that the row is loaded until 13. And the row will start again from beginning.
If I set the height of each row to 20. All the row can be loaded in one screen then everything fine.
but I need to set the height to 40. then it has the problem.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"GroupsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
NSLog(#"test indexpath = %ld",(long)indexPath.row);
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
if(indexPath.row == 0){
UIImageView *profileImageView = [[UIImageView alloc] initWithFrame:CGRectMake(10.0, 10, 80.0, 80.0)];
NSString *url = [[NSString alloc] init];
NSString *tempurl =self.iconimgpath;
NSLog(#"tempurl = %#",tempurl);
url = [NSString stringWithFormat:#"%#",tempurl];
NSURL * imageURL = [NSURL URLWithString:url];
profileImageView.contentMode = UIViewContentModeScaleAspectFit;
[profileImageView sd_setImageWithURL:imageURL placeholderImage:[UIImage imageNamed:#"loadinglogo.png"]];
profileImageView.tag = 11;
if([cell.contentView viewWithTag:11])
[[cell.contentView viewWithTag:11] removeFromSuperview];
[cell.contentView addSubview:profileImageView];
//[cell.contentView addSubview:profileImageView];
}
else{
if(_feedItems.count>0 && (indexPath.row > 0))
{
UILabel * groupnamelabel = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 15.0, 300,20)];
groupnamelabel.text = [_feedItems[indexPath.row-1] groupname];
//groupnamelabel.font = [UIFont fontWithName:#"TrebuchetMS-Bold" size:18];
groupnamelabel.tag = 99;
if([cell.contentView viewWithTag:99]){
[[cell.contentView viewWithTag:99] removeFromSuperview];
}
[groupnamelabel setFont:[UIFont systemFontOfSize:15]];
[cell.contentView addSubview:groupnamelabel];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(pushAction:)];
[groupnamelabel addGestureRecognizer:tap];
groupnamelabel.userInteractionEnabled = YES;
}
}
return cell;
I found out the problem is
self.MyGrouptableview = [[UITableView alloc] initWithFrame:CGRectMake(0,65,screenWidth,screenHeight-150) style:UITableViewStylePlain];
If I set the height of the tableview long enough everything would be alright but the user cannot scroll to the bottom.

Table view cell reload first cell content

This is how my table is populated :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CellNewsInfo *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (!cell) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
// Set up the cell
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
NSString *titleArticle=[[stories objectAtIndex: storyIndex] objectForKey: #"title"];
titleArticle = [titleArticle stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if (indexPath.row==0) {
scr=[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
scr.tag = 1;
scr.autoresizingMask=UIViewAutoresizingNone;
[cell addSubview:scr];
[self setupScrollView:scr];
UIPageControl *pgCtr = [[UIPageControl alloc] initWithFrame:CGRectMake(120, 170, 80, 36)];
[pgCtr setTag:12];
pgCtr.backgroundColor = [UIColor clearColor];
pgCtr.numberOfPages=5;
pgCtr.tintColor=[UIColor redColor];
pgCtr.pageIndicatorTintColor=[UIColor blueColor];
self.pageControl.hidden=YES;
pgCtr.currentPageIndicatorTintColor = [UIColor redColor];
pgCtr.autoresizingMask=UIViewAutoresizingNone;
[cell addSubview:pgCtr];
}
else{
cell.title.text=titleArticle;
cell.title.numberOfLines=2;
why when i scroll it , the first cell is reloading ? i just want to have that scroll view only once at the beginig .
The reason your scrollview is being added again is that the cells are being reused once they are deallocated.
You should look into creating your own custom cells if you are going to display multiple cells types in one tableView, or even using two different cell identifiers depending on if the row is 0.
CellNewsInfo *cell;
if (indexPath.row == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:#"scrollCell" forIndexPath:indexPath];
if ([cell viewWithTag:1]) {
scr = [cell viewWithTag:1];
}
else {
scr=[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
scr.tag = 1;
}
// continue customization here with scrollview
}
else {
cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
// continue customization here without scroll view
}
return cell;

ios - adding text fields to uitableviewcell programmatically not working

Rookie ios question. I am trying to create a sign up form using a table view controller. I am trying add textfields to each cell programmatically in the cellForRowAtIndexPath method but all my text fields seem to getting created on the first cell - one overlapping the other. Here is my code.
Here is how my cells are rendering. I think I am doing something goofy with the part that is reusing the cells. I did check some some other similar threads on stackoverflow but none of them helped. Could you please tell me what i am missing or is this even the way this is supposed to be done. Your inputs are really appreciated.
Thanks,
Mike
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"signUpFields" forIndexPath:indexPath];
// Configure the cell...
if (indexPath.row == 0){
//self.firstName = [[UITextField alloc] initWithFrame:CGRectMake(5, 0, 280, 21)];
self.firstName = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.firstName.placeholder = #"First Name";
self.firstName.autocorrectionType = UITextAutocorrectionTypeNo;
[self.firstName setClearButtonMode:UITextFieldViewModeWhileEditing];
//cell.accessoryView = self.firstName;
[cell.contentView addSubview:self.firstName];
}
if (indexPath.row == 1){
self.lastName = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.lastName.placeholder = #"Last Name";
self.lastName.autocorrectionType = UITextAutocorrectionTypeNo;
[self.lastName setClearButtonMode:UITextFieldViewModeWhileEditing];
//cell.accessoryView = self.lastName;
[cell.contentView addSubview:self.lastName];
}
if (indexPath.row == 2){
self.emailId = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.emailId.placeholder = #"Email Id";
self.emailId.autocorrectionType = UITextAutocorrectionTypeNo;
[self.emailId setClearButtonMode:UITextFieldViewModeWhileEditing];
//cell.accessoryView = self.emailId;
[cell.contentView addSubview:self.emailId];
}
if (indexPath.row == 3){
self.password = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.password.placeholder = #"Password";
self.password.secureTextEntry = YES;
self.password.autocorrectionType = UITextAutocorrectionTypeNo;
[self.password setClearButtonMode:UITextFieldViewModeWhileEditing];
//cell.accessoryView = self.password;
[cell.contentView addSubview:self.password];
}
self.firstName.delegate = self;
self.lastName.delegate = self;
self.emailId.delegate = self;
self.password.delegate = self;
[self.signUpTable addSubview:self.firstName];
[self.signUpTable addSubview:self.lastName];
[self.signUpTable addSubview:self.emailId];
[self.signUpTable addSubview:self.password];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Try this..
- (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];
}
if (indexPath.row == 0){
//self.firstName = [[UITextField alloc] initWithFrame:CGRectMake(5, 0, 280, 21)];
self.firstName = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.firstName.placeholder = #"First Name";
self.firstName.autocorrectionType = UITextAutocorrectionTypeNo;
[self.firstName setClearButtonMode:UITextFieldViewModeWhileEditing];
//cell.accessoryView = self.firstName;
[cell addSubview:self.firstName];
}
if (indexPath.row == 1){
self.lastName = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.lastName.placeholder = #"Last Name";
self.lastName.autocorrectionType = UITextAutocorrectionTypeNo;
[self.lastName setClearButtonMode:UITextFieldViewModeWhileEditing];
//cell.accessoryView = self.lastName;
[cell addSubview:self.lastName];
}
if (indexPath.row == 2){
self.emailId = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.emailId.placeholder = #"Email Id";
self.emailId.autocorrectionType = UITextAutocorrectionTypeNo;
[self.emailId setClearButtonMode:UITextFieldViewModeWhileEditing];
//cell.accessoryView = self.emailId;
[cell addSubview:self.emailId];
}
if (indexPath.row == 3){
self.password = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.password.placeholder = #"Password";
self.password.secureTextEntry = YES;
self.password.autocorrectionType = UITextAutocorrectionTypeNo;
[self.password setClearButtonMode:UITextFieldViewModeWhileEditing];
//cell.accessoryView = self.password;
[cell addSubview:self.password];
}
self.firstName.delegate = self;
self.lastName.delegate = self;
self.emailId.delegate = self;
self.password.delegate = self;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
no need to add again text view in table view, this is wrong. Try this, this will work for you but better you should create a custom Cell and use. That is the best way to do it, because you can use whatever you want with Cell.
Don't add them as subviews, set them as the cell's accessory view.
- (UITextField*)getTextField{
UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 20, 35)];
tf.delegate = self;
tf.textColor = [UIColor colorWithRed:.231 green:.337 blue:.533 alpha:1];
tf.autocorrectionType = UITextAutocorrectionTypeNo;
tf.borderStyle = UITextBorderStyleNone;
tf.frame = CGRectMake(0, 20, 170, 30);
tf.clearButtonMode = UITextFieldViewModeWhileEditing;
tf.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
tf.font = [UIFont systemFontOfSize:13];
return tf;
}
- (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];
cell.textLabel.font = [UIFont systemFontOfSize:13];
cell.detailTextLabel.font = [UIFont systemFontOfSize:13];
cell.detailTextLabel.numberOfLines = 2;
}
if (indexPath.section == 0) {
UITextField *tf = (UITextField*)cell.accessoryView;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.numberOfLines = 2;
tf = [self getTextField];
cell.accessoryView = cell.editingAccessoryView = tf;
[((UITextField*)cell.accessoryView) setBorderStyle:self.tableView.editing ? UITextBorderStyleRoundedRect : UITextBorderStyleNone];
[((UITextField*)cell.accessoryView) setUserInteractionEnabled:self.tableView.editing ? YES : NO];
[((UITextField*)cell.accessoryView) setTextAlignment:!self.tableView.editing ? UITextAlignmentRight : UITextAlignmentLeft];
((UITextField*)cell.accessoryView).tag = indexPath.row;
}
return cell;
}
The idea is that the cell is re-drawn each time it appears on screen, coming from off the screen and if you add the text field with addSubview:, it will add it each time as well. You COULD do it, but then you have to clear the cell's contentView of subviews, but that requires extra work, cpu and memory use, and not to say it's the least elegant solution.
Looks like you have just four cells you want to display. This is a static case, the cells don't change, you should create this tableView and its cells statically in the xib/storyboard. That is the preferred way here.
If you really want to do it programmatically, create four UITableViewCells with the behavior you want before hand. Keep them in an array. Inside cellForRowAtIndex path return cellArray[indexPath.row];
Note this is the best approach only because you have just four tableViewCells.
ReuseIdentifiers come in handy only if you have more cells than can be accommodated on the screen at once. So in your case, you never actually reuse the cells.
keep this one and try it,
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *MyIdentifier = [NSString stringWithFormat:#"%d%d",indexPath.row,indexPath.section];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
//your stuff.
}
}
Try to use this one ...And there is no need to add these textfield to tableview. So please remove some code..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"signUpFields" forIndexPath:indexPath];
// Configure the cell...
if (indexPath.row == 0){
//self.firstName = [[UITextField alloc] initWithFrame:CGRectMake(5, 0, 280, 21)];
self.firstName = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.firstName.placeholder = #"First Name";
self.firstName.autocorrectionType = UITextAutocorrectionTypeNo;
[self.firstName setClearButtonMode:UITextFieldViewModeWhileEditing];
//cell.accessoryView = self.firstName;
[cell addSubview:self.firstName];
}
if (indexPath.row == 1){
self.lastName = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.lastName.placeholder = #"Last Name";
self.lastName.autocorrectionType = UITextAutocorrectionTypeNo;
[self.lastName setClearButtonMode:UITextFieldViewModeWhileEditing];
//cell.accessoryView = self.lastName;
[cell addSubview:self.lastName];
}
if (indexPath.row == 2){
self.emailId = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.emailId.placeholder = #"Email Id";
self.emailId.autocorrectionType = UITextAutocorrectionTypeNo;
[self.emailId setClearButtonMode:UITextFieldViewModeWhileEditing];
//cell.accessoryView = self.emailId;
[cell addSubview:self.emailId];
}
if (indexPath.row == 3){
self.password = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.password.placeholder = #"Password";
self.password.secureTextEntry = YES;
self.password.autocorrectionType = UITextAutocorrectionTypeNo;
[self.password setClearButtonMode:UITextFieldViewModeWhileEditing];
//cell.accessoryView = self.password;
[cell addSubview:self.password];
}
self.firstName.delegate = self;
self.lastName.delegate = self;
self.emailId.delegate = self;
self.password.delegate = self;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Instead of writing more cells just create one custom cell with textfield.Give the tag for each textfield and also set the count of rows in numberOfRowsIntheSections then it will display the cells how much you need. I think it will helps you.
Before You follow my Answer i wnat to tell you that following code is bad for memory management because it will create new cell for each rows of UITableView, so be careful for it.
But it is better to use, When UITableView Have Limited rows (about 50-100 may be ) then following code is helpful in your case, use it, If it is suitable for you.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"S%1dR%1d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
/// Put/Create your UITextField or any Controls here
}
return cell;
}
#Mike : First of all I will suggest you to go with StoryBoard or Nib files.
If you use this, then you can use following code
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
UITextField *txtField = (UITextField *)[cell viewWithTag:1];
txtField.text = #"Latest";
return cell;
}
Based on row number you can set text.
If you want to add the UITextField at run time. then you can use following code.
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
UITextField *txtField = [[UITextField alloc] initWithFrame:CGRectMake(165.0, 7.0, 150.0, 30.0)];
txtField.text = #"Latest";
[cell.contentView addSubview:txtField];
return cell;
}
You can assign different tag and based on tags you can store those values.

UITableView dequeue not working as expected

As I scroll down the list, all the rows are there, but they keep adding more subviews the more they appear on the visible frame
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *reuse = #"RuleCell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuse];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:reuse];
}
NSUInteger row = indexPath.row;
[self createCell: cell onRow: row];
return cell;
}
- (void) createCell: (UITableViewCell*)cell onRow: (NSUInteger)row
{
UIImageView* bgImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cell_background_spade_active.png"]];
cell.backgroundView = bgImage;
cell.textLabel.hidden = YES;
UILabel* titleLabel = [[UILabel alloc] initWithFrame: CGRectMake(100, CGRectGetHeight(cell.frame) / 2, 200, 50)];
titleLabel.text = [[self.ruleList objectAtIndex: row] objectForKey: TitleKey];
titleLabel.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview: titleLabel];
}
I think you need to execute almost all of the logic that's in createCell: only within the if (cell == nil){ segment of your code. The part that should execute where you're currently calling createCell: is just getting a reference to the titleLabel and setting its text value.
To clarify, here's the kind of modification I'm suggesting (not tested, but should give the right idea):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *reuse = #"RuleCell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuse];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:reuse];
[self setUpCell: cell];
}
NSUInteger row = indexPath.row;
UILabel *titleLabel = (UILabel *)[cell.contentView viewWithTag:42];
titleLabel.text = [[self.ruleList objectAtIndex: row] objectForKey: TitleKey];
return cell;
}
- (void) setUpCell: (UITableViewCell*)cell
{
UIImageView* bgImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cell_background_spade_active.png"]];
cell.backgroundView = bgImage;
cell.textLabel.hidden = YES;
UILabel* titleLabel = [[UILabel alloc] initWithFrame: CGRectMake(100, CGRectGetHeight(cell.frame) / 2, 200, 50)];
titleLabel.tag = 42;
titleLabel.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview: titleLabel];
}

UITableView list not displaying all items

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.

Resources