I am trying to create a table with unique styling so that my label size dynamically changes with the content. I was able to get the cell to change style after it has been dequeued once (ie once I scroll down to a new page, those cells are formatted and then when I scroll back up the cells are formatted) but cannot seem to do this one the initial load. The labels are scoped only to that method because anytime I tried to make them more available, it caused the storyboard to fail.
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *pastVerse = [self.pastVerses objectAtIndex:indexPath.row];
UILabel *label;
label = (UILabel *)[cell viewWithTag:1];
label.text = [pastVerse valueForKey:#"reference"];
label = (UILabel *)[cell viewWithTag:2];
label.text = [pastVerse valueForKey:#"version"];
label = (UILabel *)[cell viewWithTag:3];
label.text = [pastVerse valueForKey:#"verse"];
[label setNumberOfLines:0];
[label sizeToFit];
Related
I really can't get my head around why this isn't working properly.
I have a TableViewController with dynamic prototypes. I put 4 labels in a prototype named "InfoCell", and gave them constraints.
If i run the app with the following cellForRowAtIndexPath:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"InfoCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
return cell;
}
what I get is this. Everything looks fine 'til now
I did this just to check that the labels were being displayed in the right place. The page is supposed to show 2 cells, so everything looks fine.
Now, the problems start when I try to get a reference to the labels in order to change the text. Even without actually changing the text, if my code looks like this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"InfoCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
UILabel *nameLabel = (UILabel *)[cell viewWithTag:10];
UILabel *surnameLabel = (UILabel *)[cell viewWithTag:20];
UILabel *roleLabel = (UILabel *)[cell viewWithTag:30];
UILabel *spouseNameLabel = (UILabel *)[cell viewWithTag:40];
[cell addSubview:nameLabel];
[cell addSubview:surnameLabel];
[cell addSubview:roleLabel];
[cell addSubview:spouseNameLabel];
return cell;
}
I get this. Labels' positions went nuts
I tried, for example, to change the frame of each label programmatically,
nameLabel.frame = CGRectMake(15.0, 50.0, 120.0, 20.0)
but it just doesn't do anything, I suppose because auto-layout is enabled... but I'm too far into the project to disable auto-layout. Plus I've seen the use of viewWithTag as I wrote above working without the need to re-locate the labels programmatically, so it bugs me not to know what's really happening there!
Remember that when you have constraints added on any of the UI object, you can't change the frame of that object by changing its CGRect. In fact, you should change its constraint value.
Now the problem in your code is ,
[cell addSubview:nameLabel];
[cell addSubview:surnameLabel];
[cell addSubview:roleLabel];
[cell addSubview:spouseNameLabel];
above 4 lines. When you have added a UILabel in storyboard, why are you adding them again by using addSubview method ? Remove above 4 lines, and to set text on your UILabel , you already have a reference which you are accessing by using their tag values. So your method should looks like as below.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"InfoCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
UILabel *nameLabel = (UILabel *)[cell viewWithTag:10];
UILabel *surnameLabel = (UILabel *)[cell viewWithTag:20];
UILabel *roleLabel = (UILabel *)[cell viewWithTag:30];
UILabel *spouseNameLabel = (UILabel *)[cell viewWithTag:40];
nameLabel.text = #"";
surnameLabel.text = #"";
roleLabel.text = #"";
spouseNameLabel.text = #"";
return cell;
}
I have an UITableViewController and I customize its UITableViewCells. Each UITableViewCell contains two UIImageViews and two UILabels. Although when I get into the UITableView the memory usage raises to 100 MB and i do not know the reason. Here is the code for the cellForRowAtIndexPath method that handles the cell customization. Can anyone help me with this issue?
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"Cell";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
UILabel *mnhmeioLabel = (UILabel *)[cell viewWithTag:102];
mnhmeioLabel.frame = CGRectMake(mnhmeioLabel.frame.origin.x,
mnhmeioLabel.frame.origin.y,
191,
21);
Group *tmpGroup = [mnhmeiaTotal objectAtIndex:indexPath.row];
NSLog(#"%# ",tmpGroup.title);
NSLog(#"%f %f", mnhmeioLabel.bounds.size.width,
mnhmeioLabel.bounds.size.height);
mnhmeioLabel.text = tmpGroup.title;
mnhmeioLabel.font = [UIFont fontWithName:#"Open Sans" size:10];
mnhmeioLabel.numberOfLines=0;
mnhmeioLabel.lineBreakMode=NSLineBreakByWordWrapping;
[mnhmeioLabel sizeToFit];
if( tmpGroup.imagesOfArticle.count > 0 ){
UIImageView *mnhmeioImageView = (UIImageView *)[cell viewWithTag:103];
mnhmeioImageView.image = [tmpGroup.imagesOfArticle objectAtIndex:0];
} else {
UIImageView *mnhmeioImageView = (UIImageView *)[cell viewWithTag:103];
mnhmeioImageView.image = [UIImage imageNamed:#""];
}
UIImageView *markerImageView=(UIImageView *)[cell viewWithTag:100];
markerImageView.image=[self selectMarker:tmpGroup];
UILabel *mnhmeioDescription = (UILabel *)[cell viewWithTag:101];
mnhmeioDescription.text=tmpGroup.constructedContent;
mnhmeioDescription.font = [UIFont fontWithName:#"Open Sans" size:6];
}
Probably, the images are big.
Or, perhaps you are not reusing the cells properly, if you are using iOS7 and Storyboards, please follow this tutorial (Prototype cells and Using subclass for a cell sections):
http://www.raywenderlich.com/50308/storyboards-tutorial-in-ios-7-part-1
Thank you all for your help. I had to decrease the size of each image as much as i could. This fixed my problem.
I have a UICollectionView that shows images, similar to cover art, or iBooks. I would like for it to show the title of the audio clip underneath the UIImageView. I have in my MainWindow.xib a View Controller with a UICollectionView inside it. I also built a NibCell.xib for the cell itself. In the Cell, I have a UIImageView that fills up all but the bottom 30 px of the cell. In this area I add a UILabel. I give the UIImageView a tag of 100 and UILabel a tag of 200, and in my code I put:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
static NSString *cellIdentifier = #"cvCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UIImageView *titleLabel = (UIImageView *)[cell viewWithTag:100];
UILabel *titleLabel2 = (UILabel *)[cell viewWithTag:200];
NSString *thearticleImage = entry.articleImage;
[titleLabel setImageWithURL:[NSURL URLWithString:entry.articleImage] placeholderImage:[UIImage imageNamed:#"icon#2x.png"]];
[titleLabel2 setText:entry.articleTitle];
return cell;
}
However, no matter how the cell is set up in NibCell.xib, it makes the UIImageView fill the entire cell, and adds the UILabel on top of it. Any suggestions?
You need to add your UILabel to cell's contentview
UILabel *title = [[UILabel alloc]initWithFrame:CGRectMake(0, 10, cell.bounds.size.width, 40)];
title.tag = 200;
[cell.contentView addSubview:title];
I have three UILabels in my custom UITableViewCell.
It might be that some UILabels will be empty (label.text == #"")
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"EventCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSString *key = [[keysArray objectAtIndex:indexPath.section] description];
UILabel *nameLabel = (UILabel *)[cell viewWithTag:100];
namelabel.text = #"Label 1";
UILabel *locationLabel = (UILabel *)[cell viewWithTag:101];
location.text = #"Label 2";
UILabel *timeLabel = (UILabel *)[cell viewWithTag:102];
timeLabel.text = #"";
return cell;
}
How can I centre all non-empty UILabels vertically in the cell using auto-layout?
This is how it looks with three labels
How it looks when one of UILables is empty
And this is how I want it to look:
This is tricky to achieve, but a simple shortcut may be to have a single label instead, with three lines of text, constrained to fill the whole height of the cell. The label will then auto-center its contents vertically.
You'd have three string properties on the cell instead of three labels, and your setters would build the final string (using \n for new lines) and set the label's text.
If each line of text has different styling, no problem, as you can use attributed strings.
I'm trying to create a tableview where the height of the cells are dynamic.
So far I manage to set the height of the cells depending on the custom UILabel I've added inside.
With the regular cell.textLabel it works fine, but when I use my own label something goes wrong. I only see half the label, but when I scroll up and down, sometimes the label extends and shows all the text... You can see where the label should end in the image.
Image
This is the text inside the cellForRowAtIndexPath:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell.
Car *carForCell = [cars objectAtIndex:indexPath.row];
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel = (UILabel *)[cell viewWithTag:100];
nameLabel.numberOfLines = 0;
nameLabel.text = carForCell.directions;
[nameLabel sizeToFit];
[nameLabel setBackgroundColor:[UIColor greenColor]];
return cell;
Unless you have typos in the code you posted, you don't seem to be adding the label to the cell at all. You also seem to be creating a new label every time, and then replacing the contents of your nameLabel pointer with the cell's view (which will always be nil).
Try doing something like this first and then see how it looks:
static NSString *CellIdentifier = #"Cell";
UILabel *nameLabel;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
nameLabel = [[UILabel alloc] init];
nameLabel.tag = 100;
nameLabel.numberOfLines = 0;
[nameLabel setBackgroundColor:[UIColor greenColor]];
[cell.contentView addSubview:nameLabel];
}
else {
nameLabel = (UILabel *)[cell viewWithTag:100];
}
// Configure the cell.
Car *carForCell = [cars objectAtIndex:indexPath.row];
nameLabel.text = carForCell.directions;
[nameLabel sizeToFit];
return cell;
You will also need to tell the tableView what size each cell needs to be using the tableView:heightForRowAtIndexPath: delegate method. That will mean getting the relevant Car object again and calculating the height using sizeWithFont:sizeWithFont:forWidth:lineBreakMode:
How are you setting the height of the cell? It should be done in - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
You should calculate and return the height of the UITableViewCell in the following method:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
Here you should do your initial calculation of how high your cell should be.
For example:
CGSize textSize = [myString sizeWithFont:[UIFont systemFontOfSize:16] constrainedToSize:CGSizeMake(320, 9999)];
return textSize.height;