I have a UITableView with prototype cells in right/left detail style. The text length of both (multiline) labels varies pretty much.
This means that the width of the labels will change in regard to the text (even within the same section).
In a more general sense, this question applies to all cells containing at least 2 labels which are aligned horizontally to each other.
Is it possible to calculate the resulting cell height (in heightForRowAtIndexPath) without a given constraining label width?
I would like to layout the text in as few lines as possible = minimizing the cell height (see picture).
Any suggestions/solutions are appreciated!
The height for the row is calculated in tableview delegate's method - tableView:heightForRowAtIndexPath:
This is where you have to calculate the possible width & height of labels. It is possible to do by using [#"LOOOONG TEXT" sizeWithFont:defaultFont]; Then just do the appropriate math and return needed height for the cell.
Related
This illustration shows what i'm trying to do:
The green list is the UITableView where it dynamically adjust it's height based on the number of items inside of it.
Underneath of the UITableView is a button that should follow the UITableView whenever it changes it's height size.
The UIButton should always be beneath the UITableView whatever the size of the UItableView.
I'm currently using autoresizing for UITableView
I have tried to use Autolayout but it seems i can't still find the answer.
i currently have no constraints in the layout.
This boils down to calculating the height of the table view that perfectly fits the cells. Basically you need to measure the size of every cell, then create a height constraint on the table view, and set its constant to the sum of the cells' heights.
Measuring the height of cells is tricky thought. If you only have a few cells (like in your illustrations), you can just instantiate all of them, keep them in an array and use systemLayoutSizeFittingSize to calculate their sizes. If you use multi-line labels, it is also important to set their preferredMaxLayoutWidth to appropriate values.
However, if you have only a few cells (and so cell reuse is not important), stack view is probably a better choice than table view. It's just too tricky to calculate the perfect height of a table view.
I am using a tableview to display a list of articles. Each cell needs to show an image and a text that has a brief descriptions of articles. What I want is to adjust the cells height depending the description length.
I know that I can resize the cells with the delegate method heightForRowAtIndexPath but I still don’t know which height to return.
Any help?
Ok, you can do that just using Interface builder. On the Tableview properties click “Row height” automatic.

Then you can use a UILabel with property lines set to 0 to display your text. When adding the constraints to the cell you need to make sure that the height of cell depends on the intrinsic content size of the label, basically is the size of the content (the text inside the label).
For example:

Here I have added a UIImage with constant height and width and with top and leading space to 0. Also I added a UILabel with top/bottom/leading/trailing space to 0. Here the cell height will depend on the UILabel intrinsic size that is what you want. Also to prevent glitches with short texts you can add a minimum height size to the UILabel.
Of course this is an example, you can achieve the same using other constraints. The main thing here is to be aware of the concept of intrinsic content size: a predetermined size of a view based in its content.
Let's say you have a textView in each cell. The width of the textView is fixed. And you know the text for each cell. Base on the info above, you can get the height of your textView by:
textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
Then you should be able to calculate the height of your cells base on your layout and stuff.
The question is answered but just in case you want to know... You can return UITableViewAutomaticDimension in heightForRowAtIndexPath.
Nevertheless you should google more before asking a question that has been answered multiple times on the web (and on stackoverflow) ;)
I am using custom cell in UITableView. There are 4 views in cell. 3 UILabels and 1 UIImageView (grey colored one) as shown below. Text of labels are dynamic so width and height is dynamic.
Here width of UIImageView depends on 2 labels. So issue is to specify constraints between labels and UIImageView that will decide the width of UIImageView.
See below what happens if first label's text is long.
How to specify constraints when width depends on width of multiple labels?
Update : I tried setting number of lines for labels to 0 and intrinsic size to placeholder. It's not working, too. Below is how it looks. I tried setting intrinsic width and height to none, but it gives error when I do that for both label, not giving error if set that for only one label.
Update : I changed properties and below is displayed what are they now and how the cell is displayed.
Cell :
Constraints for label in first row (pink colored) :
Constraints for label in second row (cyan colored) :
I solved this after experimenting with lot of things. The only thing I had to do is to set horizontal and vertical content compression resistance priority to required.i.e. 1000.
I did this for all labels because I don't want any of the labels to trim their content.
One more thing which is too much important is Getting Right Height Of Cell. If there is even 1pt of error in calculating custom cell's height it will not be displayed as expected.
Hint :
If height of any view is greater than expected then possibly calculated height of cell is greater than what is actually required.
If any of views is shrinking vertically or not displaying whole content then possibly calculated height of cell is lesser than what is actually required.
Yoy can test if height is wrong by adding/removing constant value to height (variable) you calculate for cell.
I have a table cell on which I presently have a UILabel say labelA whose height is dynamic i.e. based on the content. The label width is 290px. I wish to add another label next to labelA whose name is say labelB. The table cell and labelA looks as per below:
Question 1 - Here the height is expanding and I have 2 rows to display the entire text here. But it looks like width for the 1st and 2nd row is same as 290. Is there a way I can stop the width of the label where my text ends i.e. in this case the width of my label for 1st row should be 290 but for 2nd row it should end after the last work "Paul" so that I can start my next label labelB from there?
Question 2 - Also, while creating the xib, I am placing both my labels on the same row. If I set a constraint between both the labels, can labelA push labelB down to another row when it expands?
My cell and labels finally should look as below where the label with purple background is labelA and rect with orange border and white solid color inside is labelB.
Please let me know if this is possible? I am still a noob in iOS and auto layout.
To answer Question 1, UILabel will always draw text into a rectangular frame. You can't have one UILabel draw two lines of text the way you're looking for. You could use two UILabels, one for each line, but you'd have to do some manual calculations to figure out how much text will fit in the first label, and then what text to "overflow" to the second (boundingRectWithSize:options:attributes:context: would be your friend for this).
To answer Question 2, you should pin the bottom edge of labelB to the bottom edge of labelA. Let the height of each label be determined by the intrinsic content size. Assuming the font is the same, this should result in the result you want. (You can also try aligning the two labels' baselines, but I can't recall how that behaves for multiline labels.)
By the way, you should look into iOS 7's Text Kit. I personally haven't had a chance to dive into it in much depth yet, but it's very powerful and you might find a better way to do what you're after here.
I have 3 labels in a UITableViewCell and have the labels set so they will wordwrap. If they word wrap the text goes into the next cell. How do I get AutoLayout to expand the cell based on the content without having to write code in the heightForRowAtIndex method? Isn't there a constraint I can use to automatically adjust the cell based on the contentView?
The cell looks fine if the text doesn't wrap in the label. Once it wraps that is when the problem occurs and I would like to have the cell resize to fit the content and have the same spacing between the bottom label and the bottom as there is between the top and top label.
Unfortunately no, you can't do this. A table view calculates its own total height first and has a fixed idea of the size of each cell as they load, it won't determine it's height from the outside in and it won't let layout constraints change the height of a cell.
If you think about how tables work, with cell reuse, then you couldn't really size the table from its cells without loading in every cell and adding it to the scrollview, and performing a layout pass on the whole thing. That would probably lead to quite poor performance.
You could experiment with populating a "free" cell (i.e a cell you've just instantiated, not added to a table) and laying it out for each row in your datasource when calculating heightForRow.
As you are loading the individual cells, after you fill the labels, but before you load the instance of the cell, check the label height.
Something like:
cell.frame.size.height
If the height is large enough that you know the label has wrapped to two lines, then increase the height of the cell you are about to load.