How may I reproduce the message UITableViewCell style, without using custom cells ?
For the moment, I am using UICellStyleWithSubtitle, and I add accessories, but I can only see the date, and the UITableViewCellAccessoryDisclosureIndicator is hidden.
What I want :
http://www.askdavetaylor.com/4-blog-pics/iphone-text-txt-message-haiti-2.png
What I am doing :
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 45, 15)];
[myLabel setText:[NSString stringWithFormat:#"%#", [table returnDate]]];
[myLabel setAdjustsFontSizeToFitWidth:YES];
[myLabel setTextColor:[UIColor blueColor]];
[myLabel setBackgroundColor:[UIColor clearColor]];
cell.accessoryView = myLabel;
[myLabel release];
cell.textLabel.text = table.title;
cell.detailTextLabel.text = table.subtitle;
For this, you don't have to use UICellStyleWithSubtitle..u could use UITableViewCellStyleValue1 and try with detailTextLabel property of cell like:
cell.detailTextLabel.text = #"Yesterday";
Try this,
cell.detailTextLabel.text = [table returnDate]
instead of using label simply assign the value to detailTextLabel, and give cell style as UITableViewCellStyleValue1.
Related
I have a uitableview with 2 rows n 4 sections and i have a label and textfield in each cells. And the problems is my label comes in all section where as my textfield is not repeating in other sections. Actually i have two textfield one for each cell, one is normal textfield and another is picker textfield (when I clicked TF the picker will pop up). For one section both the TF coming but it's not repeating in other section.
My code
static NSString *CellIdentifier = #"Cell";
UITextField *textField;
NSString *string=[NSString stringWithFormat:#"ident_%d",indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:string];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.selectionStyle=UITableViewCellSelectionStyleNone;
UILabel *lbl1 = [[UILabel alloc]initWithFrame:CGRectMake(50, 10, 100, 35)];
[lbl1 setFont:[UIFont systemFontOfSize:16]];
[lbl1 setTextColor:[UIColor blackColor]];
[lbl1 setBackgroundColor:[UIColor clearColor]];
if (indexPath.row==0) {
lbl1.text = #"Quantity";
[cell.contentView addSubview:self.qntTF];
}
if (indexPath.row==1) {
lbl1.text = #"Unit";
[cell.contentView addSubview:self.unitTF];
}
// Configure the cell...;
textField =[self.tableArray objectAtIndex:indexPath.row];
[cell.contentView addSubview:textField];
cell.textLabel.text = nil;
textField.tag = TextFieldTag;
cell.detailTextLabel.text = nil;
[cell addSubview:lbl1];
[lbl1 release];
return cell;
The way the code is now, you're adding many, many more labels than you think (each time the table scrolls) and you're only adding one text field, then moving it around to different cells. It ends up on whichever cell was rendered last.
The way your cellForRow... method is now, every time row 0 and 1 for any section appears - including when the user is just scrolling them on and off the screen - another text view and label are added as subviews to the cell. Scroll up and down 100 times, there will be 100 text views and labels stacked one on top of another in the cell.
To avoid this, only add subviews when the cell is created. So in this block...
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UILabel *label = /* all of your label init */
label.tag = kSOME_UNIQUE_INT_CONST;
UITextField *textField = /* all of your text field init */
textField.tag = kSOME_OTHER_UNIQUE_INT_CONST
[cell addSubview:label];
[cell addSubview:textField];
}
Now, after the block, you can assume that each cell you has exactly one label and one textField. The next job is to find them (they were either just created, or already in the cell if it was reused)...
UILabel *label = (UILabel *)[cell viewWithTag:kSOME_UNIQUE_INT_CONST];
UILabel *textField = (UITextField *)[cell viewWithTag:kSOME_OTHER_UNIQUE_INT_CONST];
Now you're ready to configure the cell for the given section and row. The key here is to remember that you're often getting reused cells. They will still be configured for rows that have been scrolled away. So every "if" block needs a corresponding "else" block to change the subviews' states:
if (indexPath.row == 0) {
label.text = #"Quantity";
// not sure what view you were adding here, but don't
// subview adds only in the cell==nil block above
} else {
label.text = /* whatever the label should be for row != 0 */
// this is important: if you change label state in the if, you
// must specify it's state also in an else, otherwise you'll see
// leftover state on the label when the cell is reused for a different row
}
Why don't you initialise the text box the same way you do the label?
You have for the TextField:
UITextField *textField;
Then The Label:
UILabel *lbl1 = [[UILabel alloc]initWithFrame:CGRectMake(50, 10, 100, 35)];
[lbl1 setFont:[UIFont systemFontOfSize:16]];
[lbl1 setTextColor:[UIColor blackColor]];
[lbl1 setBackgroundColor:[UIColor clearColor]];
Why don't you try this near the label:
UITextField *textfield = [[UITextField alloc]initWithFrame:CGRectMake(LOCATION)];
[textfield setTextColor:[UIColor blackColor]];
[textfield setBackgroundColor:[UIColor clearColor]];
[textfield setBorderStyle:UITextBorderStyleNone];
Also it could be that your array you get your textfields from only has two textfields in it?
Also it could be because it looks like you are not instancing a new text box just adding the same one from the implementation over and over again, Example:
if (indexPath.row==0) {
lbl1.text = #"Quantity";
[cell.contentView addSubview:self.qntTF];
}
if (indexPath.row==1) {
lbl1.text = #"Unit";
[cell.contentView addSubview:self.unitTF];
}
before return the cell add [cell setNeedsDisplay]; line.
[cell setNeedsDisplay];
return cell;
it will be ok.
thanx.
I´m using the method cellForRowAtIndexPath to draw cells with 2 labels. When i reuse a cell the label i had before in that cell isn´t erased, so i get two labels overlapping because i´m reusing a cell. This is weird cause only the label title gets overlapped, the other doesn´t.
So what i did to fix this, is that i´m always creating a new cell. Which isn´t appropriate but solves the problem... Anyone had a similar bug and manage to fix it? Cause i just made a workaround...
//Desenhado por codigo
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
UILabel *label = nil;
UILabel *label2 = nil;
UIColor *green = [UIColor colorWithRed:0 green: 0.77 blue:0 alpha:1];
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
// if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"Cell"] autorelease];
//Descrição
label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setLineBreakMode:UILineBreakModeWordWrap];
[label setMinimumFontSize:FONT_SIZE];
[label setNumberOfLines:0];
[label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[label setFont:[UIFont fontWithName:#"HelveticaNeue-CondensedBold" size:14.0]];
[label setTag:1];
[label setTextColor:green];
[label setBackgroundColor:[UIColor clearColor]];
label.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"barra_cinza_lista.png"]];
[[cell contentView] addSubview:label];
label2 = [[UILabel alloc] initWithFrame:CGRectZero];
[label2 setLineBreakMode:UILineBreakModeWordWrap];
[label2 setMinimumFontSize:FONT_SIZE];
[label2 setNumberOfLines:0];
[label2 setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[label2 setFont:[UIFont fontWithName:#"HelveticaNeue-CondensedBold" size:14.0]];
[label2 setTag:2];
[label2 setTextColor:[UIColor whiteColor]];
[label2 setBackgroundColor:[UIColor clearColor]];
[[cell contentView] addSubview:label2];
}
NSString *text = [self getTableViewRow:tableView index:indexPath];
NSString *title = #" %#";
if(tableView == myTableView1)
title = [NSString stringWithFormat:title, [_titlesResults objectAtIndex:indexPath.row]];
else
title = [NSString stringWithFormat:title, [_titlesVision objectAtIndex:indexPath.row]];
CGFloat widthMax = CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2);
CGSize constraint = CGSizeMake(widthMax, 20000.0f); //Tamanho máximo permitido de largura e altura
CGSize size1 = [title sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap]; //Tamanho ocupado pelas letras
CGSize size2 = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap]; //Tamanho ocupado pelas letras
if (!label)
label = (UILabel*)[cell viewWithTag:1];
if (!label2)
label2 = (UILabel*)[cell viewWithTag:2];
[label setText:title];
[label setFrame:CGRectMake(0, 0, 320, MAX(size1.height, 44.0f))];
[label2 setText:text];
[label2 setFrame:CGRectMake(CELL_CONTENT_MARGIN, 3 * CELL_CONTENT_MARGIN + size1.height, widthMax, MAX(size2.height, 44.0f))];
return cell;
}
At the beginning of the method, enumerate through all the UIView objects in [cell.contentView subviews] and get rid of them, like so:
for (UIView *subview in [cell.contentView subviews]) {
[subview removeFromSuperview];
}
This works because all UI elements inherit from UIView and thus can be removed as if they were.
first, uncomment this line:
// if (cell == nil)
if you don't, you are simply creating and allocating a new cell every time you scroll, and never release the old ones...
Please see the code
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
UILabel *playerHeading;
UITextField *txt;
if (cell == nil)
{
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
playerHeading=[[UILabel alloc ]initWithFrame:CGRectMake(5.0f, 10.0f, 70.0f, 30.0f)];
txt=[[UITextField alloc]initWithFrame:CGRectMake(80.0f, 13.0f, 170.0f, 30.0f)];
txt.tag=2;
[txt setBackgroundColor:[UIColor clearColor]];
//[txt setTextColor:[UIColor blackColor]];
//[txt setBackgroundColor:[UIColor whiteColor]];
[txt setTextColor:[UIColor grayColor]];
txt.delegate=self;
//[txt setBorderStyle:UIBorderStyle ]
[txt setText:#"Enter Player name"];
//txt.layer.cornerRadius=8.0f;
// txt.layer.masksToBounds=YES;
//txt.layer.borderColor=[[UIColor redColor]CGColor];
// txt.layer.borderWidth= 1.0f;
[playerHeading setBackgroundColor:[UIColor clearColor]];
[playerHeading setFont:[UIFont boldSystemFontOfSize:15]];
[playerHeading setTag:1];
[playerHeading setBackgroundColor:[UIColor clearColor]];
NSString *str=[NSString stringWithFormat:#"Player %i",indexPath.row];
[playerHeading setText:str];
[playerHeading setFont:[UIFont boldSystemFontOfSize:15]];
// NSLog(#"row %i ,section %i",indexPath.row,indexPath.section);
[cell.contentView addSubview:playerHeading];
}
else
{
playerHeading = [cell.contentView viewWithTag:1];
txt=[cell.contentView viewWithTag:2];
// NSLog(#"row %i ,section %i",indexPath.row,indexPath.section);
}
if(indexPath.section%2==0){
playerHeading.textColor=[UIColor blueColor];
}
else{
playerHeading.textColor=[UIColor redColor];
}
playerHeading.text = [NSString stringWithFormat:#"Player %i",indexPath.row];
txt.tag=indexPath.section;
// NSString *nam=[NSString stringWithFormat:#"%i",indexPath.row];
// [txt setName:nam];
//txt.clearsOnBeginEditing=YES;
[cell.contentView addSubview:txt];
//cell.accessoryView=txt;
return cell;
}
I have created a UITable with 7 sections each section contains 4 players user need to fill the text fields in reach row , but issue is that when i scroll the table textfields become set to default value please help how can i set the textfields to fixed value inserted by used
For solving your problem is storing the user inserted string into a data structure which will give easy access to the string with the help of section and row.
You can use a NSMutableDictionary whose key will be section number which will store an array and the 'row' index of array will give you the string typed in that particular text field.
In cellForRowAtIndexPath you will have to check if string exists for that cell else show default string or placeholder.
In my cellForRowAtIndexPath, I'm doing some custom formatting on a subview for when that cell is selected. The complete function is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIView *left;
UIImageView *leftImage;
UILabel *label;
ArticleButton *btn;
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (!cell)
{
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:#"UITableViewCell"] autorelease];
left = [[[UIView alloc] initWithFrame:CGRectMake(0, 2, 155, 139)] autorelease];
leftImage = [[[UIImageView alloc] initWithFrame:CGRectMake(7,9,141,77)] autorelease];
label = [[[UILabel alloc] initWithFrame:CGRectMake(6,87,141,48)] autorelease];
btn = [[[ArticleButton alloc] initWithFrame:CGRectMake(0,2,155,139)] autorelease];
left.tag = 0;
leftImage.tag = 1;
label.tag = 2;
btn.tag = 3;
[btn addTarget:self action:#selector(selectArticle:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:left];
[cell.contentView addSubview:leftImage];
[cell.contentView addSubview:label];
[cell.contentView addSubview:btn];
}
else
{
left = (UIView*)[cell viewWithTag:0];
leftImage = (UIImageView*)[cell viewWithTag:1];
label = (UILabel*)[cell viewWithTag:2];
btn = (ArticleButton*)[cell viewWithTag:3];
}
...load *entry
NSURL *url = [NSURL URLWithString:[entry imageUrl]];
FeedEntry* selectedEntry = [detailViewController detailItem];
NSString* selectedTitle = selectedEntry.title;
if ([selectedTitle isEqualToString:entry.title])
{
[left setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellbackground_sel.png"]]]; <-- PROBLEM IS THIS IMAGE NEVER CHANGES
NSLog(#"selected row %#", selectedTitle);
}
else{
[left setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellbackground2.png"]]];
}
[left setNeedsDisplay];
[leftImage setImageWithURL:url placeholderImage:[UIImage imageNamed:#"placeholder.gif"]];
[leftImage setContentMode:UIViewContentModeScaleAspectFill];
leftImage.clipsToBounds = YES;
[label setBackgroundColor:[UIColor clearColor]];
label.textColor = [UIColor whiteColor];
label.text = [entry.title stringByAppendingString:#"\n\n"];
label.numberOfLines = 3;
label.lineBreakMode = UILineBreakModeClip;
label.font = [UIFont fontWithName:#"Arial-BoldMT" size:12];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
The problem I'm having is with this section:
if ([selectedTitle isEqualToString:entry.title])
{
[left setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellbackground_sel.png"]]];
NSLog(#"selected row %#", selectedTitle);
}
else{
[left setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellbackground2.png"]]];
}
Everything else works, but although I'm logging that it gets called, but the background of my subview to indicate that the row in question is a selected row, never changes. I've tried calling setNeedsDisplay, I've tried scrolling up and down trying to get the cells to dequeue and get recreated, it just never users the other image, even though it logs that the row being drawn was a selected row.
(Once I get this working, I need to implement the "right" section to have two "cells" in the one row and only one will be selected. That's why I'm doing it this way with subviews in the cell).
What am I doing wrong?
I think it is a problem to set the tag to zero. The documentation says:
viewWithTag:
Return Value
The view in the receiver’s hierarchy whose tag property matches the value in the tag parameter.
Discussion
This method searches the current view and all of its subviews for the specified view.
If think that most views tag is zero, even that of the current cell's view. I think that you dont get the correct view out of it. Try not to use 0 as a tag to work with.
Whenever a particular UITableViewCell is selected, this particular delegate is called -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Try to see if your button taps are being first responded by this delegate rather than going to selectArticle: selector you have defined...
Instead of setting this in tableview:cellForRowAtIndexPath:, try doing it in the tableview:willSelectRowAtIndexPath:
See the protocol reference for further details.
I have this code below to populate my UITableView on the fly.
I have to display two kind of cells: a regular cell with a background image and a cell with a regular background image, plus a label and a button.
if Indexpath.row is less than a control variable, then regular cells are drawn. If not, cells with buttons and labels are drawn.
this is the code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
UIImage *imageU;
if (indexPath.row < controlVariable) {
imageU = [[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:[NSString stringWithFormat: #"table%d", indexPath.row] ofType:#"jpg"]] autorelease];
cell.imageView.image = imageU;
} else {
imageU = [[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:[NSString stringWithFormat: #"table-pg%d",numberX]
ofType:#"jpg"]] autorelease];
cell.imageView.image = imageU;
NSString * myString = [NSString stringWithFormat: #"pago%d", numberX];
UILabel * myLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 49.0, 200.0, 22.0)];
[myLabel setTextAlignment:UITextAlignmentLeft];
[myLabel setBackgroundColor:[UIColor blueColor]];
[myLabel setClipsToBounds:YES];
[myLabel setFont:[UIFont systemFontOfSize:14.0]];
[myLabel setTextColor:[UIColor blackColor]];
[myLabel setText: myString];
[myLabel setAlpha:0.6];
[cell addSubview: myLabel];
[myLabel release];
UIButton *buyButton = [[UIButton alloc] initWithFrame:CGRectMake( 220, 4, 100, 35)];
buyButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
buyButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[buyButton setTitle:NSLocalizedString(#"buyKey", #"") forState:UIControlStateNormal];
[buyButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
buyButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];
UIImage *newImage = [[[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource: #"whiteButton" ofType:#"png"]] autorelease]
stretchableImageWithLeftCapWidth:12.0f topCapHeight:0.0f];
[buyButton setBackgroundImage:newImage forState:UIControlStateNormal];
[buyButton addTarget:self action:#selector(comprar:) forControlEvents:UIControlEventTouchDown];
buyButton.backgroundColor = [UIColor clearColor];
[buyButton setTag:indexPath.row];
[cell addSubview:buyButton];
[buyButton release];
}
return cell;
}
The problem with this code is: when I scroll the UITableView down and reach the division between regular cells and cells with buttons and labels, I see it is rendering correctly, but if I go up after going deep down, I see the buttons and labels being added to cells that were not supposed to have them. From this point forward, all cells contains buttons and labels...
It is like the cells are not releasing its contents before drawing. It is like labels and buttons are being added on top of other buttons and labels already on the cell. Cells are not releasing its contents before drawing again.
How to solve that?
thanks for any help.
NOTE: I see barely no difference after making the changes suggested by the two first answers. Now, not all cells are wrong, just some. They change every time I scroll down the table and return to the beginning of the table.
You should use a separate reuseIdentifier for each cell 'type' that you are using. In this case, you'll want to use two.
You'll also want to create/add the UILabel and UIButton when you get a dequeue miss and not for every run through.. In pseudocode:
UILabel * lbl;
UIButton * btn;
cell = [table dequeueReusableCellWithIdentifier:correctIdentifier];
if (cell == nil)
{
cell = ...; // alloc cell
lbl = ...;
lbl.tag = kTagLabel;
[cell addSubView:lbl];
btn = ...;
btn.tag = kTagButton;
[cell addSubView:btn];
}
else
{
lbl = (UILabel*)[cell viewWithTag:kTagLabel];
btn = (UIButton*)[cell viewWithTag:kTagButton];
}
//... now set the text/image appropriately.
Otherwise, you create a label and button each time the cell is dequeued from the table. Scrolling up and down will cause lots of labels and buttons to be created that never get released.
You should use two different reuseIdentifiers; one for cells with just images, and one for cells with images and buttons. The problem is that your one cell type is being reused, but its content is not (nor should it be) cleared out when it's dequeued.