I have a UICollectionView that I'm trying to use as a matrix with a first "column" used as the name of the row (colors) and then in the other items I put how many goods I'm buying. I had to split it in two collections because the header has to be fixed in that position.
My problem is that the initial situation is this:
Then, when I scroll the gray collection a bit and play with it...
The code which should manage the part is this:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
CGSize cellSize = cell.frame.size;
int item = (int)indexPath.item;
int section = (int)indexPath.section;
NSLog(#"S:%d I:%d",section,item);
/*NSMutableArray *array = [matrice objectAtIndex:section];
if([array objectAtIndex:row] != [NSNull null]){
cell = [[matrice objectAtIndex:section] objectAtIndex:10-row];
return cell;
}else{
[[matrice objectAtIndex:section] replaceObjectAtIndex:row withObject:cell];
}*/
if(item == 0){ //Colori
int labelWidth = cellSize.width - 5;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake((cellSize.width/2)-labelWidth/2, (cellSize.height/2)-labelWidth/2, labelWidth, labelWidth)];
Colore *colore = [cartellaColore.arrayColori objectAtIndex:section];
[label setText:colore.descrizione];
[label setTextAlignment:NSTextAlignmentCenter];
[label setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:14]];
[cell addSubview:label];
[cell setBackgroundColor:[UIColor whiteColor]];
}
else{
[cell setBackgroundColor:[UIColor grayColor]];
}
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(2*section, 2*item, 35, 10)];
[label setText:[NSString stringWithFormat:#"S:%d I:%d",section,item]];
[label setTextAlignment:NSTextAlignmentCenter];
[label setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:8]];
[cell addSubview:label];
return cell;
}
What am I doing wrong?
EDIT:
I let the program write different label on the same cell just for showing that the indexpaths are wrong. If they were correct it would just re-add the label in the same position with the same text (which I know is still wrong but it was just for debugging)
You can't add a label like that in your cellForRowAtIndexPath, you have to subclass a UICollectionViewCell.
I made a response to this kind of issue here : UICollectionView adding image to a cell
Just apply what I explained to a UILabel instead of a UIImageView, and your issues should disappear.
Let me know though.
This is your mistake:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(2*section, 2*item, 35, 10)];
[label setText:[NSString stringWithFormat:#"S:%d I:%d",section,item]];
[label setTextAlignment:NSTextAlignmentCenter];
[label setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:8]];
**[cell addSubview:label];**
you are stacking labels in cells, the cell are reusable, and each time you dequeue a reusable cell you add a label to it so if the dequeued cell has already been presented you will add another label to it and ect. You should protect your self from that by checking if that cell already has label and if it has than just change its text property, and if it doesn't do the code above... One way to do it is to add a specific tag to the label and then when you dequeue a cell just check if it has a view with that tag, if it has cast the view to label and change its text property so:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
if([cell viewWithTag:111]){
UILabel *label = (UILabe*)[cell viewWithTag:111];
[label setText:[NSString stringWithFormat:#"S:%d I:%d",section,item]];
}
else{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(2*section, 2*item, 35, 10)];
[label setText:[NSString stringWithFormat:#"S:%d I:%d",section,item]];
[label setTextAlignment:NSTextAlignmentCenter];
[label setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:8]];
[label setTag:111];
[cell addSubview:label];
}
...
Related
I have a basic UICollectionView that if I scroll will "redraw" the label on top of the cells,
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
cell.backgroundColor=[UIColor greenColor];
UILabel *title = [[UILabel alloc]initWithFrame:CGRectMake(0, 10, cell.bounds.size.width, 40)];
[cell.contentView addSubview:title];
//NSString *titleLbl = [NSString stringWithFormat:#"i = %d", indexPath.row];
title.text = [self.arraya objectAtIndex:indexPath.row];
return cell;
}
How to fix it so it refreshes the proper cell after scrolling?
Cheers
When you do this:
UILabel *title = [[UILabel alloc]initWithFrame:CGRectMake(0, 10, cell.bounds.size.width, 40)];
[cell.contentView addSubview:title];
You're creating a new title every time and adding it to your contentView. Instead, try adding a tag to your UILabel and changing your existing UILabel's text, like so:
UILabel *title = (UILabel *)[cell.contentView viewWithTag:SOME_NUMBER];
if (!title) {
title = [[UILabel alloc]initWithFrame:CGRectMake(0, 10, cell.bounds.size.width, 40)];
title.tag = SOME_NUMBER;
[cell.contentView addSubview:title];
}
title.text = #"your new text"
this is a noob question.i subclassed my table view cell in interface builder and created a table view.what i want is to change the color of the textlabel to UITableViewCellStyleValue1 color(light blue).since i created the cell in .nib file.i m not able to use cell.detailtextlabel.text.could u guys help me out.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[NSBundle mainBundle] loadNibNamed:#"CCell" owner:self options:nil] objectAtIndex:0];
}
UILabel *lbl=(UILabel*)[cell viewWithTag:1];
UIImageView *imgV = (UIImageView*)[cell viewWithTag:2];
UILabel *label=(UILabel*)[cell viewWithTag:3];
NSDictionary *dToAccess = [self.listOfItems objectAtIndex:indexPath.row];
[lbl setText:[dToAccess valueForKey:#"title"]];
NSUInteger intVal = [[dToAccess valueForKey:#"rating"] integerValue];
switch (intVal) {
case 0:
[imgV setImage:[UIImage imageNamed:#"0star.png"]];
[label setText:#"Snitt 0"];
label.textColor=[UIColor blueColor];
break;
case 1:
[imgV setImage:[UIImage imageNamed:#"1star.png"]];
[label setText:#"Snitt 1"];
break;
case 2:
[imgV setImage:[UIImage imageNamed:#"2star.png"]];
[label setText:#"Snitt 2"];
break;
case 3:
[imgV setImage:[UIImage imageNamed:#"3star.png"]];
[label setText:#"Snitt 3"];
break;
case 4:
[imgV setImage:[UIImage imageNamed:#"4star.png"]];
[label setText:#"Snitt 4"];
break;
case 5:
[imgV setImage:[UIImage imageNamed:#"5star.png"]];
[label setText:#"Snitt 5"];
break;
default:
break;
}
CGSize size = [lbl.text sizeWithFont:[UIFont boldSystemFontOfSize:16] forWidth:205 lineBreakMode:UILineBreakModeCharacterWrap];
[lbl setFrame:CGRectMake(5, 0, size.width, 43)];
[imgV setFrame:CGRectMake(5+size.width+5, 4, 118, 36)];
return cell;
}
You can get the detail label cell color for UITableViewCellStyleValue1 by doing:
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"resuse"];
UIColor *lightBlueColor = cell.detailTextLabel.textColor;
which can be broken down into it's RGB values and alpha by doing:
const float* colors = CGColorGetComponents( lightBlueColor.CGColor );
It's up to you if you want to hardcode the values in code or just compute it every time. I'd say hardcode would be better.
The trick is getting hold of the label on which to set the color. If you've rolled your own cell, a quick thing to do is give your label a tag value in the nib, (look for it along with the other view properties of your label).
Then when you're configuring the cell, get the label like this:
UILabel *label = (UILabel *)[cell viewWithTag:16]; // 16 is a unique in the view, non-zero int that you make up yourself
label.textColor = [UIColor redColor];
The alternative is to connect outlets from your nib to properties on a custom cell, but tags might be a simpler way to start out.
I'm trying to add an extra UILabel into each cell(UITableView)
I'v succeeded with this code in
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method
Here's my code
//add another text
UILabel *test = [[UILabel alloc] initWithFrame:CGRectMake(250,80,50,20.0)];
test.text = [NSString stringWithFormat: #"test"];
test.backgroundColor = [UIColor clearColor];
test.font=[UIFont fontWithName:#"AppleGothic" size:20];
[cell addSubview:test];
However I figured that if I do this, I can't add different text to each cell, instead, it ends up with the same text in all cells. Can anyone tell me how to do that?
Oh and another problem was that if I do this, "test" is displayed in every cell except for the first one.
Have a look at the tutorial "UITableView – Adding subviews to a cell’s content view".
Try something like this
- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier {
CGRect CellFrame = CGRectMake(0, 0, 320, 65);
CGRect Label1Frame = CGRectMake(17,5,250,18);
UILabel *lblTemp;
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:cellIdentifier] autorelease];
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
[lblTemp setFont:[UIFont fontWithName:#"Arial-BoldMT" size:15]];
lblTemp.tag = 1;
lblTemp.backgroundColor=[UIColor clearColor];
lblTemp.numberOfLines=0;
[cell.contentView addSubview:lblTemp];
return cell; // this I forgot
}
in cellForRowAtIndexPath
{
if(cell == nil)
cell = [self getCellContentView:CellIdentifier];
UILabel *lblTemp1 = (UILabel *)[cell viewWithTag:1];
lblTemp1.text =[nameArray objectAtIndex:value+indexPath.row];
return cell;
}
For having the same Label on all cells, you are probably instantiating just one cell and use the cellReUseIdentifier for all cells. So, I suggest that you create different labels as properties of the class, and assign each property-label to each cell.
// For example -
if (indexPath.row ==0 )
// assign [cell.contentView addSubview: self.label1];
if (indexPath.row ==1 )
// assign [cell.contentView addSubview: self.label2];
And for the second part of the question, please post your cellForRowAtIndexPath fully - there could be an error in that.
First check if any of the predefined styles work for you.
If you need more flexibility than what they offer, you can try something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [self makeCell: CellIdentifier];
}
MyData *data = [self.data objectAtIndex:indexPath.row];
UILabel *lbl1 = (UILabel *)[cell viewWithTag:1];
UILabel *lbl2 = (UILabel *)[cell viewWithTag:2];
lbl1.text = data.text;
lbl2.text = data.auxText;
return cell;
}
- (UITableViewCell *)makeLensListCell: (NSString *)identifier
{
CGRect lbl1Frame = CGRectMake(10, 0, 140, 25);
CGRect lbl2Frame = CGRectMake(10, 150, 140, 25);
UILabel *lbl;
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier] autorelease];
// Label with tag 1.
lbl = [[UILabel alloc] initWithFrame:lbl1Frame];
lbl.tag = 1;
[cell.contentView addSubview:lbl];
[lbl release];
// Label with tag 2.
lbl = [[UILabel alloc] initWithFrame:lbl2Frame];
lbl.tag = 2;
lbl.textColor = [UIColor lightGrayColor];
[cell.contentView addSubview:lbl];
[lbl release];
// Add as many labels and other views as you like
return cell;
}
This approach also allows images and other views.
I cannot get my UITableView to load data as i am scrolling. I do have subview in the cell (two lines). It display the first screen correctly but when i scroll only the lines that is on the first screen displays, nothing to scroll.
I have two arrays cellArray1 (main line) and cellArray2 (second line) that I load data from.
I would very much appreciate help to solve this, possible, simple problem.
Here is what i think is relevant code for this question:
- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier
{
CGRect CellFrame = CGRectMake(0, 0, 300, 60);
CGRect Label1Frame = CGRectMake(10, 10, 290, 25);
CGRect Label2Frame = CGRectMake(30, 33, 270, 25);
UILabel *lblTemp;
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:cellIdentifier] autorelease];
//Initialize Label with tag 1.
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
lblTemp.backgroundColor = [UIColor orangeColor];
[lblTemp setFont:[UIFont fontWithName:#"American Typewriter" size:16]];
lblTemp.tag = 1;
[cell.contentView addSubview:lblTemp];
[lblTemp release];
//Initialize Label with tag 2.
lblTemp = [[UILabel alloc] initWithFrame:Label2Frame];
lblTemp.backgroundColor = [UIColor orangeColor];
lblTemp.tag = 2;
[lblTemp setFont:[UIFont fontWithName:#"American Typewriter" size:13]];
lblTemp.textColor = [UIColor whiteColor];
[cell.contentView addSubview:lblTemp];
[lblTemp release];
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) cell = [self getCellContentView:CellIdentifier];
UILabel *lblTemp1 = (UILabel *)[cell viewWithTag:1];
UILabel *lblTemp2 = (UILabel *)[cell viewWithTag:2];
lblTemp1.text = [cellArray1 objectAtIndex:indexPath.row];
lblTemp2.text = [cellArray2 objectAtIndex:indexPath.row];
tableView.backgroundColor = [UIColor orangeColor];
return cell;
}
The answer to this problem was that I had hard coded a parameter that dictate how many items that was loaded during my testing.
I just found the problem, i had hard coded a parameter that dictated how many items that was
Make sure you are adding to the correct view if you are creating programatically and adding as subview to main view.
I have this wierd problem with my table
i Have about 20 cells to display
Each cell is about 84px in height
When i click no the cell, i have set a background colour
The first 4 cells are ok, but when i scroll down and click on the 5th cell, the content of each cell starts to overlap with some other content, usually content from 1st 4 cells.
I belive its some cell reusability or drawing issue. Am not sure how to solve it, i have checked through my code, but i am not changing the cell's content on touch.
Here is my code and will add some pics too
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 104;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [stores count];
}
-(UITableViewCell *)tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
CGRect Label1Frame = CGRectMake(5, 5, 250, 30);
CGRect Label2Frame = CGRectMake(6, 42, 220, 20);
CGRect Label3Frame = CGRectMake(6, 62, 220, 20);
CGRect Label4Frame = CGRectMake(240,56, 70, 12);
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}else{
// a cell is being recycled, remove the old edit field (if it contains one of our tagged edit fields)
UIView *viewToCheck = nil;
viewToCheck = [cell.contentView viewWithTag:1];
if (!viewToCheck) {
[viewToCheck removeFromSuperview];
DebugLog(#"View removed");
}
}
//cell.selectionStyle=UITableViewCellSelectionStyleNone;
[cell setSelectedBackgroundView:bgView];
NSInteger row=indexPath.row;
UILabel *lblTemp;
[[cell contentView] clearsContextBeforeDrawing];
//Line 1
lblTemp=[[UILabel alloc] initWithFrame: Label1Frame];
lblTemp.tag=1;
lblTemp.text=[[stores objectAtIndex:row] objectAtIndex:0] ;
lblTemp.numberOfLines=2;
lblTemp.font = [UIFont boldSystemFontOfSize:13];
lblTemp.adjustsFontSizeToFitWidth=YES;
lblTemp.minimumFontSize=12;
lblTemp.textColor = [UIColor grayColor];
[cell.contentView addSubview:lblTemp];
[lblTemp release];
//Line 2
lblTemp = [[UILabel alloc] initWithFrame:Label2Frame];
lblTemp.tag = 2;
lblTemp.text=[[stores objectAtIndex:row]objectAtIndex:1];
lblTemp.font = [UIFont systemFontOfSize:12];
lblTemp.textColor = [UIColor grayColor ];
lblTemp.textAlignment=UITextAlignmentLeft;
lblTemp.adjustsFontSizeToFitWidth=YES;
lblTemp.minimumFontSize=12;
[cell.contentView addSubview:lblTemp];
[lblTemp release];
//Line 3
lblTemp = [[UILabel alloc] initWithFrame:Label3Frame];
lblTemp.tag = 3;
lblTemp.text=[[stores objectAtIndex:row]objectAtIndex:2];
lblTemp.font = [UIFont systemFontOfSize:12];
lblTemp.textColor = [UIColor grayColor ];
[cell.contentView addSubview:lblTemp];
[lblTemp release];
//Phone button
UIButton *phoneButton=[[UIButton alloc] initWithFrame:CGRectMake(240,16,30,30)];
[phoneButton setBackgroundImage:[UIImage imageNamed:#"phone.png"] forState:UIControlStateNormal];
[phoneButton setTag:row];
[phoneButton addTarget:self action:#selector(dialNumber:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:phoneButton];
//ANnotation button
UIButton *annotation=[[UIButton alloc] initWithFrame:CGRectMake(274,16,30,30)];
[annotation setTag:row];
[annotation setBackgroundImage:[UIImage imageNamed:#"tab.png"] forState:UIControlStateNormal];
[annotation addTarget:self action:#selector(openMap:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:annotation];
[annotation release];
//Distance label
//Line 3
lblTemp = [[UILabel alloc] initWithFrame:Label4Frame];
lblTemp.tag = 4;
lblTemp.text=[[stores objectAtIndex:row]objectAtIndex:5];
lblTemp.textAlignment=UITextAlignmentCenter;
lblTemp.font = [UIFont systemFontOfSize:13];
lblTemp.textColor = [UIColor grayColor ];
[lblTemp setAdjustsFontSizeToFitWidth:YES];
[cell.contentView addSubview:lblTemp];
[phoneButton release];
[lblTemp release];
[cell setNeedsLayout];
[cell setNeedsDisplay];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell=[tableView cellForRowAtIndexPath:indexPath ];
for(UILabel *lbl in cell.contentView.subviews){
if([lbl isKindOfClass:[UILabel class]]){
lbl.textColor=[UIColor whiteColor];
}
}
//UITableViewCell *cell1;
//NSString *row=[NSString stringWithFormat:#"%d",indexPath.row];
svm = [[storesMapView alloc] initWithNibName:#"storesMapView" bundle:nil];
[svm initWithXML:stores:indexPath.row];
CGRect theFrame = svm.view.frame;
theFrame.origin = CGPointMake(self.view.frame.size.width, 0);
svm.view.frame = theFrame;
theFrame.origin = CGPointMake(0,0);
theFrame.size=CGSizeMake(320,355);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3f];
svm.view.frame = theFrame;
[UIView commitAnimations];
[subView addSubview:svm.view];
backButton.hidden=NO;
}
I figured it out with some trial and error; if this can help some one
In cellforRowAtIndexPath i tried to clear all the cells subview before drawing the cell
//TRY TO REMOVE ALL CONTENT
for(UIView *view in cell.contentView.subviews){
if ([view isKindOfClass:[UIView class]]) {
[view removeFromSuperview];
}
}
I would be happy if someone can point me to some easier way
Thanks
You can use
[[[cell contentView] subviews] makeObjectsPerformSelector: #selector(removeFromSuperview)];
If the cell in not nil, the above code will reduce the time for using the for loop similar to this
for(UIView *eachView in [cell subviews])
[eachView removeFromSuperview];
I also had the same issue.I also had composed tableView with labels.And when I scroll it down the contents got overlapped.But it got solved simply by editing one statement in cellForRowAtIndexPath.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
I think this will solve your problem.
I know this is a bit late, but I had a similar issue where UILabels created for a cell were still part of the cell when it was reused. So each successive update of the tableview created another UILabel on top of the existing one. I moved the creation of the Labels into the if condition as below and it resolved my issue. Hope it helps someone else. Also note no release as I am using ARC.
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cityText = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 100, 20)];
cityText.font = [UIFont fontWithName:#"Arial" size:20];
cityText.textAlignment = UITextAlignmentLeft;
cityText.backgroundColor = [UIColor clearColor];
regionText = [[UILabel alloc] initWithFrame:CGRectMake(10, 40, 100, 20)];
regionText.font = [UIFont fontWithName:#"Arial" size:20];
regionText.textAlignment = UITextAlignmentLeft;
regionText.backgroundColor = [UIColor clearColor];
}
Setting nil to label text on UITableViewCell subclass 's method prepareForReuse() solved my problem -
override func prepareForReuse() {
super.prepareForReuse()
self.label1.text = nil
self.label2.text = nil
....
}
Shared if it helps anyone!