How can you set a UILabel's height to exactly match its font size? - ios

I've got a UI design spec to follow where the spacing between text is precisely specified i.e. here's a spec for vertical spacing in a table view cell:
The problem when using a storyboard and constraints is that when you place a UILabel in the storyboard its height is larger then its contained font size (so you can't for example set a vertical constraint of 6 between the two line in the spec for example, as that would set the UILabels 6 points apart, not the contained text 6 apart).
Here's a diagram to make it clear what I mean:
Here the constraint is 6px. But I want to be able to set the distance between the bottom of the text of Label1 and the top of the text of label 2 to be 6.
By setting a vertical constraint of 6 between the labels, the distance between the text within those labels is greater than 6.
I attempted to solve this by using a custom label:
#IBDesignable
class NoPaddingLabel: UILabel {
override var alignmentRectInsets: UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
}
But this doesn't adjust the height of the UILabel in the storyboard despite the #IBDesignable - for example if you drag and drop a UILabel then by default its System font size 17, with a height of 21. If its type is changed from UILabel to NoPaddingLabel its height is still 21.
If constraints are then added there's tones of errors regarding vertical compression and vertical hugging priorities conflicts.
So, is there a way to calculate the height of the UILabel in the storyboard to correspond to the height of its font so that its easier to set exact vertical constraints between text? -
Whats the solution to set exact constraint distances between text, rather than between labels in a storyboard?

Related

Multicolumn list with flexible columns width - iOS

I want to create list with two columns. Text in first column should be aligned to left and text in second column should be aligned to right. Space between columns should be constant. Different cases depends on texts length should be covered:
1.
Text 123
TextText 12
Tex 123
Text 1
Te 123456
T 12
Te 1234
Te 1
Text 123
TextText 12
TextTextTextTextText 123
Text 1
Both columns should have flexible width depends on the longest text. They also should have some minimum width so it will not be completely invisible if text in other column will be too long. Whole list also should have flexible width, of course there is some max width and then text in first column should be divided into lines. I don't want to divide into lines text in second column as long as I don't have to.
How to create such list?
I try to use for it two stack views one next to the other. These two stack views I have in my custom control. My custom control is added to container view using xib and have constraints equals to 0 for top, leading and bottom and greater or equals 0 for trailing. To these stack views I add labels programatically and I also set content hugging priority for them (first label has lower priority than second one). One think stil doesn't work, first stack view is as width as first label in this stack view. It doesn't change his width when other labels with longer texts are added. Is it possible to have working solution without calculating stack views width manually?
private void Initialize()
{
_firstStackView = new UIStackView
{
TranslatesAutoresizingMaskIntoConstraints = false,
Axis = UILayoutConstraintAxis.Vertical,
Spacing = 4
};
_secondStackView = new UIStackView
{
TranslatesAutoresizingMaskIntoConstraints = false,
Axis = UILayoutConstraintAxis.Vertical,
Spacing = 4,
Alignment = UIStackViewAlignment.Trailing
};
Add(_firstStackView);
Add(_secondStackView);
AddConstraints();
}
private void AddConstraints()
{
NSLayoutConstraint.ActivateConstraints(
new[]
{
_firstStackView.LeadingAnchor.ConstraintEqualTo(LeadingAnchor),
_secondStackView.LeadingAnchor.ConstraintEqualTo(_firstStackView.TrailingAnchor, 20),
TrailingAnchor.ConstraintEqualTo(_secondStackView.TrailingAnchor),
_firstStackView.TopAnchor.ConstraintEqualTo(TopAnchor),
_firstStackView.BottomAnchor.ConstraintEqualTo(BottomAnchor),
_secondStackView.CenterYAnchor.ConstraintEqualTo(_firstStackView.CenterYAnchor),
_secondStackView.WidthAnchor.ConstraintGreaterThanOrEqualTo(WidthAnchor, 0.25f),
_firstStackView.WidthAnchor.ConstraintGreaterThanOrEqualTo(WidthAnchor, 0.25f),
});
}
You can use UICollectionView to create list with two columns. Space between columns and grid size can be adjusted by changing UICollectionViewLayout.
Implement text adaptive width and height:
Instantiate UILabel
Set the UILabel property to get the text content and font
Calculate the size according to text and font
Use CGSize to set the maximum width you want
Set the frame according to the size
You can see some useful info here
For more details, you can refer to the following doc:
Collection Views in Xamarin.iOS | Microsoft Docs

change hight of the tableView cell does not work

hello guys now I have UITableViewCell should have dynamic height , this cell have 3 labels , I have added them in to stack and I added all requirements
to let tableViewCell be dynamic height
1- The code used for automatic cell height
notifications.rowHeight = UITableView.automaticDimension
notifications.estimatedRowHeight = 150
2- I have set constraints leading and trailing and bottom and top space to the superView.
3- The number of lines for each label is equal zero
this is cell before run
enter link description here
this cell after run https://ibb.co/5YCMpfK
The constraints of your tableViewCell must be like:
Properties of stackView:
Axis: Vertical
Alignment: Fill
Distribution: Fill Proportionally
Spacing: 5 (as per your requirement)
Number of lines of all 3 labels = 0
Check if your stack view doesn't have height constraint.
Check if your labels do not have any height constraint.
Give your stackview top and bottom constraints a specific value and make them greater than equal to topContraint >= 5 bottomconstraint >=5.
Change the property of stack view to Fill proportionally and give spacing according to your needs.

Custom UITableViewCell - adjust UILabel vertical alignment dynamically

I have a custom table cell. It has two labels (title and description), one below the other.
What I have right now is, title label top = topMargin. And description label top = title label bottom + 10.
But in some cases, there will be no description. In such cases, I want the title label to be centered vertically inside the cell. Is this possible? What constraints do I have to set?
A UIStackView makes it easy to do what you want.
Create a prototype cell
add two labels
embed them in a stack view
set the stack view's properties to:
Axis: Vertical
Alignment: Fill
Distribution: Fill Equally
Spacing: 10
constrain the stack view Top/Leading/Trailing/Bottom to 0 to the cell's content view's default margins (or set your own "padding")
set your fixed row height - with default labels + 10-point spacing + top and bottom margins, you'll probably want at least 67
connect the labels to IBOutlets
When you set the text of the labels in cellForRowAt indexPath:, set the description label's .isHidden property to true if it has a description, or to false if it doesn't.
The result (with background colors for clarity):
The result without background colors:

Which Constraint we need to make dynamic View height in iOS

As I am new to iOS. So forgive me if it is duplicate or very basic question.
I am taking one View. Approx below is the size .
x : 5 y : 5
Width : 590 Height : 100
and I set constraint it
Top to superView 5
Trailing to superView 5
Leading to superView 5
Now I have one Label which have dynamic Text and the Text is too large.
And the Label Constraint is below
Top to superView 5
Trailing to superView 5
Leading to superView 5
and when i set the background color of the View the color is not set. If the Text is to Long. So how to set the Height of the View and also set background so that it looks clear.
Code :
public override void ViewDidLoad()
{
base.ViewDidLoad();
lbl_one.Text = "This is a long label which have long text inside the writing. This is a long label which have long text inside the writing. This is a long label which have long text inside the writing. This is a long label which have long text inside the writing";
lbl_one.LineBreakMode = UILineBreakMode.WordWrap;
lbl_one.Lines = 0;
view_main.BackgroundColor = UIColor.Red;
}
If I give fix Height then it look like this .
Output :
1. Give the below constraints to your view, height is according to your need. here I'm giving 80.
2. Change the height relationship.
3. Add aUILabel in your above UIview, and give below constraints.
--> leading, top, bottom, trailing to uiview and height i.e. 80.
4. set height relationship as you do with UIView.
5. Change the property of UILabel , Lines to zero
6. Now enjoy with your constraints.
EDIT: Add bottom constraint to your view instead of height constraint.
I don't see and bottom constraint added to UIView, so the view height will be 0.
If you have added the height constraint to UIView, there is a probability that UILablel might be overlapping the UIView, so you are not able to see the background color.
Set the UIView height constraint this will solve your problem
You can also add height or bottom constraint to your UIView.

Grow TableViewCell height with wrapping Label

I have the following four Labels in a custom TableViewCell which currently look like this:
I have this:
The first, third and fourth labels have their width constraints fixed and maximum number of lines set to 1. The second Label fills the horizontal space between labels one and three.
I would like the second Label to wrap to a maximum of 2 lines and be vertically aligned to the top so that the first line of each label are aligned like this:
I want this:
I have made the background colour of each label grey so that the constraints can be seen.
You can achieve this using self sizing cells. To make that work add those two lines to your UITableview:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 50
Then in Interface Builder set the following constraints in your Prototype Cell:
Uncheck "Constraint to margins" on all constraints.
Label 1:
top: 10
left: 10
bottom: greaterOrEqual 10
width: 60 (or whatever the actual width is)
Label 2:
top: 10
left: 10
bottom: 10
Label 3:
top: 10
left: 10
bottom: greaterOrEqual 10
width: 60 (or whatever the actual width is)
Label 4:
top: 10
left: 10
right: 10
bottom: greaterOrEqual 10
width: 60 (or whatever the actual width is)
If you set the constraints like this, the cell height automatically gets higher when the second label wraps its text into a second line.
To top align the UILabels, you can either set the margin top constraint of all UILabels to be constant, or set the top align constraints. To set the top align constraints, select the label and ctrl-drag from the label to another. Select top alignment from the popup.
One thing to keep in mind is that for the second label, set the 4 margin lengths to be around 5pt, but do not constrain its width or height like the others.
Maximum of 2 lines can be configured in the right utilities panel after selecting the second label.
To dynamically change the height of the cell is a little trickier. First you should know if the text is long enough to stretch the label into 2 lines and the height of the label. (See Here) If the text is long enough to take two lines, the method will return a height value that is larger than it would normally. Based on this height change, use the following UITableViewDelegate to dynamically change the height of that UITableViewCell:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Hope this helps.

Resources