I have problem with using dequeueReusableCellWithIdentifier method. Whenever I use this one, one cell would display its own value and value that does not belong to it. This first and second images show the problem, while the third image shows the proper data.The problem seems to be caused by old value not being wiped off and the new value being added on top if it. Which seems very strange.
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell =nil ;
if(indexPath.row==0){
cell = [[[UITableViewCell alloc]init]autorelease];
}else {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSMutableArray *rowArray = [results objectAtIndex:indexPath.section];
NSString *value=nil;
if (indexPath.section==0) {
// the row in the 0th section is patient's sticky
value = [rowArray objectAtIndex:indexPath.row];
cell.textLabel.text = value;
}else {
//the row in the 1th section are lab tests
//here rowArray is tableRecords
NSArray *rowrecordTemp = [rowArray objectAtIndex:indexPath.row];
UILabel *label= [[UILabel alloc]initWithFrame:CGRectMake(5, 0, 130, tableView.rowHeight-5) ];
value = [rowrecordTemp objectAtIndex:0];
label.text= value;
[cell.contentView addSubview:label];
[label release];
label = nil;
label = [[UILabel alloc] initWithFrame:CGRectMake(140, 0, 50.0,
tableView.rowHeight-10)];
value = [rowrecordTemp objectAtIndex:1];
label.text = value;
[cell.contentView addSubview:label];
[label release];
label = nil;
label = [[UILabel alloc] initWithFrame:CGRectMake(190, 0, 90, tableView.rowHeight-10)];
value = [rowrecordTemp objectAtIndex:2];
label.text = value;
[cell.contentView addSubview:label];
[label release];
label = nil;
NSLog(#"%#\t\t%#\t\t\t\t\n%#",[rowrecordTemp objectAtIndex:0] ,[rowrecordTemp objectAtIndex:1],[rowrecordTemp objectAtIndex:2]);
}
NSString *fontname = cell.textLabel.font.fontName;
cell.textLabel.font = [UIFont fontWithName:fontname size:16];
cell.textLabel.numberOfLines = 0;
return cell;
}
Table view cells are shared in memory. When you dequeue a new one, it will have the value of an old one (I think the last one to be dequeued). You have to clear it of its old contents to display its new contents.
If you're doing something along the lines of cell.textLabel.text = [arr objectAtIndex:indexPath.row] there's no problem because the text will simply be replaced. If you have a custom view or something more complicated, you have to completely replace the view.
When (section != 0) you're adding new UILabels to the UITableViewCell. Everytime a cell is dequeued, new labels are added to it. You should either remove the old labels, or change the text of the old label instead of creating a new one.
Related
I'm trying to add a UITextField as a subview to my table cells. The content of the text fields is fine until I start scrolling and the cells start to be reused. The images illustrate the problem.
At first, the blue values on the right in the UITextField are correct, i.e. the value corresponds to the row number. The second and third images, scrolled down and back up, show that the values are being reused in odd ways.
How do I avoid this? Using unique values for reuseIdentifier solves this problem, but obviously it's not very efficient.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITextField *numberTextField;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
numberTextField = [[UITextField alloc] initWithFrame:CGRectMake(200, 10, 95, 30)];
numberTextField.adjustsFontSizeToFitWidth = YES;
numberTextField.textColor = [UIColor blueColor];
numberTextField.placeholder = #"Enter value";
numberTextField.keyboardType = UIKeyboardTypeDecimalPad;
numberTextField.tag = ([indexPath row]+1);
numberTextField.backgroundColor = [cell backgroundColor];
numberTextField.textAlignment = NSTextAlignmentRight;
numberTextField.clearButtonMode = UITextFieldViewModeNever;
numberTextField.clearsOnBeginEditing = YES;
[numberTextField setEnabled:YES];
[cell addSubview:numberTextField];
} else {
numberTextField = (UITextField *)[cell.contentView viewWithTag:([indexPath row]+1)];
}
cell.textLabel.text = [NSString stringWithFormat:#"Row %i",[indexPath row]+1];
numberTextField.text = [NSString stringWithFormat:#"Value: %i",[indexPath row]+1];
return cell;
}
The problem is you only assign the tag to the numberTextField when it is created. If it gets reused, it doesn't get its tag reassigned.
You should use a constant tag number for the UITextField instead of using row+1.
-(IBAction)btnSaveScore:(id)sender
{
if(!dictWinData)
dictWinData = [[NSMutableDictionary alloc] init];
array = [NSMutableArray arrayWithObjects:txt_EnterName.text,
[NSString stringWithFormat:#"%i",iTap], nil];
int increment = 0;
NSLog(#"array data is:--> %#",array);
for (int intWinData = 1; intWinData < [array count]; intWinData++)
{
[dictWinData setObject:array forKey:[NSString stringWithFormat:#"NameScore%d",increment]];
increment++;
}
}
This is the code to add my score of the game with name.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [dictWinData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
ArrStr = [dictWinData valueForKey:[NSString stringWithFormat:#"NameScore%d",indexPath.row]];
UILabel *lblDayName = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 160, 21)];
lblDayName.text = [ArrStr objectAtIndex:0];
lblDayName.textColor = [UIColor blackColor];
lblDayName.font = [UIFont boldSystemFontOfSize:17.0];
lblDayName.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:lblDayName];
[lblDayName release];
UILabel *lblLow = [[UILabel alloc] initWithFrame:CGRectMake(180, 50, 40, 21)];
lblLow.text = [ArrStr objectAtIndex:1];
lblLow.textColor = [UIColor blackColor];
lblLow.font = [UIFont boldSystemFontOfSize:17.0];
lblLow.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:lblLow];
[lblLow release];
}
return cell;
}
This is storing name & score of the player but each time it displays only one record in the table.
It must show the last top ten scores in the list.
Main problem is that this is not storing & showing every score data.
Please guide me to solve this problem.
Thanks in advance.
You need to give the tag of each and every control that you want to display in UITableView and outside the cell==nil condition you need to retrieve that control with the specific tag and then give the text assignment to it.
You cannot use table view for storing data. Table view is an UI Element which can be used for display your data. UITableView reference.
For storing data you can use:
Core data
Sqlite
Plist
I have a UITableView with regular UITableViewCell, but I don't use any of UITableViewCell's lables. I just use the cell to embed a label and a UITextField to input some data. Problem is when you scroll up or scroll down and the UITableviewCell redraws itself, it draws an overlapping UITextFieldView over the old one and you see doubles! I'm thinking that maybe since I do put these UITextFields into a dictionary, it might save the textfield with a strong pointer, and try to make another one and just overlap. Anyone have any suggestions?
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ProductCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *product = [self.products objectAtIndex:indexPath.row];
NSDictionary *orderpoint = [self.orderpoints objectAtIndex:indexPath.row];
cell.textLabel.text = #""; //black out text
CGFloat calculatedHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath];
UILabel *productLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, cell.bounds.size.width - 50.0, calculatedHeight)];
productLabel.text = [[NSString alloc] initWithFormat:#"%#. %#",
[orderpoint objectForKey:#"sequence_nr"], [product objectForKey:#"name"]];
//word wrapping
productLabel.lineBreakMode = UILineBreakModeWordWrap;
productLabel.numberOfLines = 0; //infinite number of lines
productLabel.font = [UIFont fontWithName:#"Helvetica" size:14.0];
[cell.contentView addSubview:productLabel];
//create the cell's textfield
UITextField *cellTextField = [[UITextField alloc] initWithFrame:CGRectMake(cell.bounds.size.width - 50, cell.bounds.size.height - 30, 50, calculatedHeight - 20)];
cellTextField.adjustsFontSizeToFitWidth = YES;
cellTextField.textColor = [UIColor blackColor];
cellTextField.keyboardType = UIKeyboardTypeNumberPad; // will only need to end a count
cellTextField.returnKeyType = UIReturnKeyDone; // TODO make it go to the next items key, or make it exit out
cellTextField.backgroundColor = [UIColor whiteColor];
cellTextField.textAlignment = UITextAlignmentLeft; //align to the right
//cellTextField.delegate = self; //will need to set delegate, maybe
cellTextField.clearButtonMode = UITextFieldViewModeNever;
cellTextField.enabled = YES;
cellTextField.borderStyle = UITextBorderStyleRoundedRect; //add bezel rounded look to textfield
cellTextField.delegate = self;
[cell.contentView addSubview: cellTextField]; //add the textfield to the cell
// save to dictionary, using a dictionary because not certain if this is created in order to use an Array
[self.textFieldDict setObject:cellTextField forKey:[[NSNumber alloc] initWithInteger:indexPath.row]];
return cell;
}
You have not initialized your cell.Try this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ProductCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//It will check whether cell in there or not, then deque the cell...
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *product = [self.products objectAtIndex:indexPath.row];
NSDictionary *orderpoint = [self.orderpoints objectAtIndex:indexPath.row];
cell.textLabel.text = #""; //black out text
CGFloat calculatedHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath];
UILabel *productLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, cell.bounds.size.width - 50.0, calculatedHeight)];
productLabel.text = [[NSString alloc] initWithFormat:#"%#. %#",
[orderpoint objectForKey:#"sequence_nr"], [product objectForKey:#"name"]];
//word wrapping
productLabel.lineBreakMode = UILineBreakModeWordWrap;
productLabel.numberOfLines = 0; //infinite number of lines
productLabel.font = [UIFont fontWithName:#"Helvetica" size:14.0];
[cell.contentView addSubview:productLabel];
//create the cell's textfield
UITextField *cellTextField = [[UITextField alloc] initWithFrame:CGRectMake(cell.bounds.size.width - 50, cell.bounds.size.height - 30, 50, calculatedHeight - 20)];
cellTextField.adjustsFontSizeToFitWidth = YES;
cellTextField.textColor = [UIColor blackColor];
cellTextField.keyboardType = UIKeyboardTypeNumberPad; // will only need to end a count
cellTextField.returnKeyType = UIReturnKeyDone; // TODO make it go to the next items key, or make it exit out
cellTextField.backgroundColor = [UIColor whiteColor];
cellTextField.textAlignment = UITextAlignmentLeft; //align to the right
//cellTextField.delegate = self; //will need to set delegate, maybe
cellTextField.clearButtonMode = UITextFieldViewModeNever;
cellTextField.enabled = YES;
cellTextField.borderStyle = UITextBorderStyleRoundedRect; //add bezel rounded look to textfield
cellTextField.delegate = self;
[cell.contentView addSubview: cellTextField]; //add the textfield to the cell
return cell;
}
Either don't use reusability and always alloc the cell at each time or
make a check after dequeue (like this)
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil)
{
// make text field and label an add tag
}
//and outside this by using tag fetch the labels and textField and clear the textFields.
You forgot to put the condition like this:
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:CellIdentifier];
}
Used this as a reference: add subviews to UITableViewCell
I just first checked to see if this view was added from before, and if it was, then don't add it again. It has nothing to do with the cell being nil. Unless I missed something? all I know is that this seems to be working fine, now.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ProductCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *product = [self.products objectAtIndex:indexPath.row];
NSDictionary *orderpoint = [self.orderpoints objectAtIndex:indexPath.row];
cell.textLabel.text = #""; //black out text
CGFloat calculatedHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath];
UILabel *productLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, cell.bounds.size.width - 50.0, calculatedHeight)];
productLabel.text = [[NSString alloc] initWithFormat:#"%#. %#",
[orderpoint objectForKey:#"sequence_nr"], [product objectForKey:#"name"]];
//word wrapping
productLabel.lineBreakMode = UILineBreakModeWordWrap;
productLabel.numberOfLines = 0; //infinite number of lines
productLabel.font = [UIFont fontWithName:#"Helvetica" size:14.0];
[cell.contentView addSubview:productLabel];
if (![cell viewWithTag:1])
{
//create the cell's textfield
UITextField *cellTextField = [[UITextField alloc] initWithFrame:CGRectMake(cell.bounds.size.width - 50, cell.bounds.size.height - 30, 50, calculatedHeight - 20)];
cellTextField.adjustsFontSizeToFitWidth = YES;
cellTextField.textColor = [UIColor blackColor];
cellTextField.keyboardType = UIKeyboardTypeNumberPad; // will only need to end a count
cellTextField.returnKeyType = UIReturnKeyDone; // TODO make it go to the next items key, or make it exit out
cellTextField.backgroundColor = [UIColor whiteColor];
cellTextField.textAlignment = UITextAlignmentLeft; //align to the right
cellTextField.delegate = self; //will need to set delegate, maybe
cellTextField.clearButtonMode = UITextFieldViewModeNever;
cellTextField.enabled = YES;
cellTextField.borderStyle = UITextBorderStyleRoundedRect; //add bezel rounded look to textfield
cellTextField.delegate = self;
cellTextField.tag = 1; //set tag to 1
[cell.contentView addSubview: cellTextField]; //add the textfield to the cell
// save to dictionary, using a dictionary because not certain if this is created in order to use an Array
[self.textFieldDict setObject:cellTextField forKey:[[NSNumber alloc] initWithInteger:indexPath.row]];
}
return cell;
}
I am trying to implement UITableview based application. In my tableView their is 10 Section and each section having one row.
I want implement each section have Different type of ContentView(1-8 same ContentView 9th section Different ContentView). I did this code For that.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 10;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"Cell1";
static NSString *CellIdentifier2 = #"Cell2";
UITextField *textField;
UITextView *textView;
NSUInteger section=[indexPath section];
if(section == 9){
UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
//UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if(cell==nil){
cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1]autorelease];
textView=[[UITextView alloc]initWithFrame:CGRectMake(5, 5, 290, 110)];
[textView setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor
]];
[textView setTag:([indexPath section]+100)];
[cell.contentView addSubview:textView];
}else{
textView=(UITextView*)[cell.contentView viewWithTag:([indexPath section]+100)];
}
return cell;
}else {
UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if(cell==nil){
cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2]autorelease];
textField=[[UITextField alloc]initWithFrame:CGRectMake(5, 5, 290, 50)];
[textField setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor]];
[textField setTag:([indexPath section]+100)];
[cell.contentView addSubview:textField];
}else{
textField=(UITextField*)[cell.contentView viewWithTag:([indexPath section]+100)];
}
return cell;
}
return nil;
}
My problem are:
1. After type some thing in the UITextField/UITextView i am scrolling in the UITableView. that time all data in the UITableViewCell(UITextField/UITextView) was lose, except last cell data.
2. If i create cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Instead of
UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
Data will repeating . How can i over come this problem?
This line:
UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
Should never appear in your data source cellForRowAtIndexPath method.
Apart from that, your code is OK, except that you are not setting the text field value anywhere. You need a model (such as an array of strings for the 10 textfield values). This model should be updated when the textfields are edited, and in your method above you copy the value back out of the model and into the textfield's text property:
textfield.text = [self.modelArray objectAtIndex:indexPath.section];
The table pools and reuses cells in an unpredictable fashion, so that subview of a cell that just scrolled off the bottom might reappear next at the top, or might be disposed of.
This is why you saw it partially work. The cell's subviews work okay until their cell gets reused or unloaded, then things move to the wrong place or data disappears.
The solution is that your table's datasource needs to hold onto it's own data. This is usually an array representing your model. Your case is a little unusual because you are using the text controls in your table as inputs, rather than display, which is more typical.
I suggest doing it like this:
// in #interface
#property (nonatomic, retain) NSMutableArray *sections;
// in #implementation
#synthesize sections=_sections;
// at some point before the view appears
self.sections = [NSMutableArray array];
for (int i=0; i<10; i++) {
UIControl *textControl;
if (i<9) {
textControl=[[UITextView alloc]initWithFrame:CGRectMake(5, 5, 290, 110)];
} else {
textControl=[[UITextField alloc]initWithFrame:CGRectMake(5, 5, 290, 50)];
}
[textControl setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor]];
[textControl setTag:i+100];
[sections addObject:textControl];
[textControl release];
}
Now your cellForRowAtIndexPath is a little simpler:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier1 = #"Cell1";
static NSString *CellIdentifier2 = #"Cell2";
NSUInteger section=[indexPath section];
if(section == 9) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if(cell==nil) {
cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1]autorelease];
}
} else {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if(cell==nil) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2]autorelease];
}
}
// who knows what subview this cell has? it might not have one, or it might have the wrong one
// just clean it up to be certain
for (UIView *view in cell.subviews) {
[view removeFromSuperView];
}
// get the textControl we set up for _this_ section/cell
UIControl *textControl = [self.sections objectAtIndex:section];
// now we have a fresh cell and the right textControl. drop it in
[cell addSubview:textControl];
return cell;
}
hey the reason is you are doing this things when cell is nil ? but you are not writing any code when cell is not nil.
look at this example , in this example i am adding image view in tableview cell , hence you can add textviews or any other views like this
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIImageView *imgView;
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
imgView = [[UIImageView alloc] initWithFrame:CGRectMake(100,0,100,62)];
[imgView setImage:[UIImage imageNamed:#"img.png"]];
imgView.tag = 55;
[cell.contentView addSubview:imgView];
[imgView release];
}
else
{
imgView = (id)[cell.contentView viewWithTag:55];
}
so as showin here imgView = (id)[cell.contentView viewWithTag:55]; you have to give tag to you and write code showing above in else..
Let you try to make the cell labels and textviews by using following code. It works for me.
if (tagvalue ==3) {
static NSString *CellIdentifier = #"Cell3";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier] autorelease];
}
lbl7 = [[UILabel alloc] init];
[lbl7 setFont:[UIFont boldSystemFontOfSize:20]];
[cell.contentView addSubview:lbl7];
lbl7.backgroundColor = [UIColor clearColor];
lbl7.frame = CGRectMake(120, 5, 0, 40);
lbl7.tag = 70;
[lbl7 release];
lbl8 = [[UILabel alloc] init];
[lbl8 setFont:[UIFont boldSystemFontOfSize:18]];
[cell.contentView addSubview:lbl8];
lbl8.backgroundColor = [UIColor clearColor];
lbl8.textColor = [UIColor grayColor];
lbl8.frame = CGRectMake(120, 50, 0, 40);
lbl8.tag = 80;
[lbl8 release];
lbl7 = (UILabel*)[cell.contentView viewWithTag:70];
lbl8 = (UILabel*)[cell.contentView viewWithTag:80];
lbl7.text = [[rowsarray objectAtIndex:row]objectForKey:#"name"];
lbl8.text = [[rowsarray objectAtIndex:row]objectForKey:#"flavour"];
[lbl7 sizeToFit];
[lbl8 sizeToFit];
return cell;
}
if (tagvalue ==4) {
static NSString *CellIdentifier = #"Cell4";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
lbl9 = [[UILabel alloc] init];
[lbl9 setFont:[UIFont boldSystemFontOfSize:20]];
[cell.contentView addSubview:lbl9];
lbl9.backgroundColor = [UIColor clearColor];
lbl9.frame = CGRectMake(120, 5, 0, 40);
lbl9.tag = 90;
[lbl9 release];
lbl10 = [[UILabel alloc] init];
[lbl10 setFont:[UIFont boldSystemFontOfSize:18]];
[cell.contentView addSubview:lbl10];
lbl10.backgroundColor = [UIColor clearColor];
lbl10.textColor = [UIColor grayColor];
lbl10.frame = CGRectMake(120, 50, 0, 40);
lbl10.tag = 100;
[lbl10 release];
lbl9 = (UILabel*)[cell.contentView viewWithTag:90];
lbl10 = (UILabel*)[cell.contentView viewWithTag:100];
lbl9.text = [[rowsarray objectAtIndex:row]objectForKey:#"name"];
lbl10.text = [[rowsarray objectAtIndex:row]objectForKey:#"flavour"];
[lbl9 sizeToFit];
[lbl10 sizeToFit];
return cell;
}
I had same issue. Its not the problem with table class. The issue is at the place where you are calling this tableviewcontroller. First make the object of this call in .h and then allocate in .m, thats it..
When I was declaring in viewdidload like tbl *t = [self.storyboard...];, I was also facing the same problem. But when I put tbl *t; in .h problem solved.
I have used Cell.ContentView in my implementation for customizing the cell contents. It works fine but the only problem is when I have many cells and I scroll them up and down, the cell contents gets overwritten into the cells just become hidden followed by visible. Suppose I scroll first cell up and then again takes it down, the last cell's contents gets overwritten on first cell!!
I debugged enough on this but couldn't find the exact solution. I tried checking Cell.ContentView.SubViews count and if it 0 then only add other subviews. This doesn't display any cell contents until I scroll them up and down but once contents appeared, it doesn't overwrite..Little bit strange..!! I also made sure that I am using reusing the cell correctly. Following is my code that adds subviews into cell's contentview. Please let me know how could I get rid of this issue.
P.S: Don't worry about the variables and calculations I have done. Assume that it returns correct values. :)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSInteger totalAvailableSpace = IPHONE_DISPLAY_WIDTH - iconSize - accesorySize - 10;
NSInteger lableHeight = [[cellDetails objectForKey:#"TableItemTextFontSize"] intValue] * 2 + 10;
UILabel *textLabel = nil;
textLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+12, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.8, lableHeight)] autorelease];
textLabel.numberOfLines = 2;
textLabel.lineBreakMode = UILineBreakModeWordWrap;
textLabel.textAlignment = UITextAlignmentLeft;
textLabel.text = [cellDetails objectForKey:#"TableItemMainText"];
if ([textLableColor scanHexInt:&hex]) {
textLabel.textColor = UIColorFromRGB(hex);
}
textLabel.font = [UIFont fontWithName:[cellDetails objectForKey:#"TableItemTextFontName"] size:[[cellDetails objectForKey:#"TableItemTextFontSize"] intValue]];
[cell.contentView addSubview:textLabel];
textLabel.backgroundColor = [UIColor clearColor];
lableHeight = [[cellDetails objectForKey:#"TableItemDetailTextFontSize"] intValue] * 2 + 10;
UILabel *detailTextLabel = nil;
detailTextLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+10+totalAvailableSpace * 0.8+5, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.2 - 10, lableHeight)] autorelease];
detailTextLabel.numberOfLines = 2;
detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
detailTextLabel.textAlignment = UITextAlignmentLeft;
detailTextLabel.text = [cellDetails objectForKey:#"TableItemDetailText"];
if ([detailTextLableColor scanHexInt:&hex]) {
detailTextLabel.textColor = UIColorFromRGB(hex);
}
detailTextLabel.font = [UIFont fontWithName:[cellDetails objectForKey:#"TableItemDetailTextFontName"] size:[[cellDetails objectForKey:#"TableItemDetailTextFontSize"] intValue]];
[cell.contentView addSubview:detailTextLabel];
detailTextLabel.backgroundColor = [UIColor clearColor];
return cell;
}
Thanks.
That is because toy are adding the views to your cell over and over again.
You should only add them when you create the cell and just set the labels when the cell is being reused.
You could set tags for your label, so that you can set it texts afterwards. The code bellow does the trick
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
if(style == UITableViewCellStyleValue1)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
else
cell = [[[UITableViewCell alloc] initWithStyle:style reuseIdentifier:CellIdentifier] autorelease];
NSInteger totalAvailableSpace = IPHONE_DISPLAY_WIDTH - iconSize - accesorySize - 10;
NSInteger lableHeight = [[cellDetails objectForKey:#"TableItemTextFontSize"] intValue] * 2 + 10;
UILabel *textLabel = nil;
textLabel.tag = 1;
textLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+12, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.8, lableHeight)] autorelease];
textLabel.numberOfLines = 2;
textLabel.lineBreakMode = UILineBreakModeWordWrap;
textLabel.textAlignment = UITextAlignmentLeft;
textLabel.text = [cellDetails objectForKey:#"TableItemMainText"];
if ([textLableColor scanHexInt:&hex]) {
textLabel.textColor = UIColorFromRGB(hex);
}
textLabel.font = [UIFont fontWithName:[cellDetails objectForKey:#"TableItemTextFontName"] size:[[cellDetails objectForKey:#"TableItemTextFontSize"] intValue]];
[cell.contentView addSubview:textLabel];
textLabel.backgroundColor = [UIColor clearColor];
lableHeight = [[cellDetails objectForKey:#"TableItemDetailTextFontSize"] intValue] * 2 + 10;
UILabel *detailTextLabel = nil;
detailTextLabel.tag = 2;
detailTextLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+10+totalAvailableSpace * 0.8+5, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.2 - 10, lableHeight)] autorelease];
detailTextLabel.numberOfLines = 2;
detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
detailTextLabel.textAlignment = UITextAlignmentLeft;
detailTextLabel.text = [cellDetails objectForKey:#"TableItemDetailText"];
if ([detailTextLableColor scanHexInt:&hex]) {
detailTextLabel.textColor = UIColorFromRGB(hex);
}
detailTextLabel.font = [UIFont fontWithName:[cellDetails objectForKey:#"TableItemDetailTextFontName"] size:[[cellDetails objectForKey:#"TableItemDetailTextFontSize"] intValue]];
[cell.contentView addSubview:detailTextLabel];
detailTextLabel.backgroundColor = [UIColor clearColor];
} else {
UILabel *textLabel = (UILabel *)[cell viewWithTag:1];
textLabel.text = [cellDetails objectForKey:#"TableItemMainText"];
UILabel *detailTextLabel = (UILabel *)[cell viewWithTag:2];
detailTextLabel.text = [cellDetails objectForKey:#"TableItemDetailText"];
}
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
}
Make sure that dequeueReusableCellWithIdentifier and reuseIdentifier should be nil
Now it will work !!
Place all the cell UI content inside if(cell==nil){uilabel,uilabel or anythingUI related} ...since ui should be call only once at time of creating cel
To be clear, your problem is that as you scroll a cell into view you will often wind up with the text of the new cell being written over the top of a cell that was just scrolled offscreen?
The problem is that dequeueReusableCellWithIdentifier: doesn't "clean up" the cell (it calls prepareForReuse, but that's it), so all your old subviews are still in place. If you are going to reuse cells, you shouldn't be recreating these subviews each time. Instead, just adjust the properties of the existing subviews on a cell you get back from dequeueReusableCellWithIdentifier:, and only create the new subviews on a newly-allocated cell. Subclassing UITableViewCell can help with this, both to provide properties/ivars in which to hold references to these subviews and to organize the code a little nicer by moving the creation of subviews and the updating into appropriate methods. Or you could just not reuse cells, by passing nil for the reuse identifier.
The most likely reason that it didn't display any content until you scroll up and down is that a newly-created cell may have the framework-provided text field and image view, which may then be removed if the framework determines that you aren't actually using them.
In iOS5 UILineBreakModeWordWrap is deprecated. You should use NSLineBreakByWordWrapping instead.
This would change you code to look like detailTextLabel.lineBreakMode = NSLineBreakByWordWrapping and textLabel.lineBreakMode = NSLineBreakByWordWrapping.