Getting two adjacent UILabels to both align on the inside edge - ios

I have a UIView which contains two UILabel objects, which are populated programmatically. I want the left UILabel to be right-aligned, and the right UILabel to be left-aligned. This is my pretty ASCII representation:
___________________
| ______ ______ |
| | ASDF| |ASDF | |
| |______| |______| |
|___________________|
I have tried all sorts of masks and alignment properties to no avail. Here is what I thought the correct solution would be, so perhaps someone can point out the flaw in my understanding.
The container UIView needs UIViewAutoResizingFlexibleWidth so that it can expand to fit labels with variable widths. Both the left and the right UILabel need UIViewAutoResizingFlexibleWidth so that they expand to fit content with variable width. The left UILabel needs UIViewAutoresizingFlexibleRightMargin so that the left margin remains fixed. The right UILabel needs UIViewAutoresizingFlexibleLeftMargin so that the right margin remains fixed.
Conceptual problem with this implementation:
As the texts expand, they could just expand over each other as that would still fit the container
I am having the overlap problem, as well as the right margin does not seem to be fixed like it is supposed to, rather there is just a large gap on the right side.
Does anyone know what might be a solution?

the UILabel view does not automatically resize itself based on text. you might need to call sizeToFit every time you change the text. You also need to handle assigning the number of lines manually if want the text to wrap.
Plus, shouldn't the left label be UIViewAutoresizingFlexibleLeftMargin and vice versa? the other way around.

Two observations:
AutoresizingMasks don't expand a view based upon changes of the view's subviews, but rather on the basis of the change in the superview. That's not of interest here. It's generally more useful on things like when the superview changes dimensions as a result of orientation changes. There are other situations that you might theoretically use autoresizingMasks, but I don't think this is one of them.
More logically, you could simply calculate with width of the text labels necessary to fit the desired text, and then set the UILabel's frame accordingly.
To calculate the size of the two text labels, once you set their text property, could do something like:
CGSize leftSize = [leftLabel.text sizeWithFont:leftLabel.font forWidth:self.view.frame.size.width lineBreakMode:UILineBreakModeWordWrap];
CGSize rightSize = [rightLabel.text sizeWithFont:rightLabel.font forWidth:self.view.frame.size.width lineBreakMode:UILineBreakModeWordWrap];
Now that you know the size of the two labels, you can tweak the frame of the two labels, as well as their superview, accordingly.

Related

Chat TableView Cell: A UIView, whose size should depend on the larger containing label

I want to make a chat table cell, with content label and a time label.
Requirements are:
The blue UIView's size (width) should depend on the wider label within it.
The UIView should leave at least 61 dpi to the right of the cell.
The label should be able to wrap the text inlined in it.
This is the structure:
Thanks for your help!
Give the label constraints that go to the edges of its superview according to what you want
Set constraints on the view so that its size is not restricted to a specific height, e.g. use a combination of constraints with lower priorities and inequality constraints (i.e. greater or less than or equal to). Not entirely sure what your goal is so I can't really be more specific.
Set the number of lines of the label to 0

Determine width of UITextView in heightForRowAtIndexPath with auto layout

A rather convoluted problem, looking for an elegant solution:
A UITableViewCell subclass has a UILabel on the left and a UITextView on the right. Both label and text view have dynamic content. I am using the text view rather than another label because I need the address link recognition.
The label has a higher compression resistance than the text view, so that its right edge will expand towards the right as needed (up to a certain limit). The text view's width will in turn be compressed. The text view is set to word wrap to expand downward.
Because a text view is a itself a UIScrollView, the normal automatic dimension mechanism of a dynamically sized table view cells view will not work (i.e. using UITableViewAutomaticDimension). Thus, I tried to implement heightForRowAtIndexPath. To determine the necessary height, I thought just need:
The text in the label, plus its attributes
The text in the text view, plus its attributes
The width of the table view (as it is "plain" rather than "grouped")
With this information, I reckoned, I can use sizeThatFits on helper objects to determine the necessary height.
However, I am reluctant to hard-code the horizontal margins between the label and the text view into my size calculation, so theoretically I additionally need NSLayoutConstraint outlets for
The left margin of the label to its superview
The max allowed width of the label
The horizontal distance between the label and the text field
The right margin of the text field to its superview
This seems really insane! While I was writing the implementation of this, I asked myself if there is not an easier way to accomplish the same. (That's why I did not yet write the code to post here.) After all, the only hard problem here is how to get the available width for the text view, but the way to getting there seems unduly complex.
Any ideas for a concise, elegant solution?
Side notes: This has to be calculated before the cell is rendered to be displayed. Also, setting the text view's scrollingEnabled to false produces weird results when using sizeThatFits.

Truncate UILabel before it runs into another UILabel dynamically

Basically, I have this situation:
Two UILabels in a UITableViewCell. They're both constrained to the top of the cell. One is constrained to the left of the cell, and one is constrained to the right of the cell.
There exists a change that the UILabel on the left can run into the UILabel on the right. Is there anyway to truncate the text x points before it gets to the UILabel on the right?
Right now, I handle this by giving the UILabel on the left an explicit width that ensures it will truncate before reaching the UILabel, but the explicit width is not dynamic based on screen size. If there is a larger screen size, it might not need to be truncated. I'm new to iOS development and am not sure how to do this.
The best way to achieve this is in auto-layout. Make sure the label on the right is a fixed size, you can even change it programatically if you need to accommodate to screen size. But the thing is this one needs a width constraint. The label on the left does not have a width constraint, instead do a horizontal spacing in front of it to the cell border and from it's trailing end to the start of the label view on the right. It will widen and shrink to fit the size that's left for it.

Modify how auto resize works on UIView?

I have a UIView that is sized to fit the entire screen minus 5 pixels on each side. I have set it to autoresize however this makes the view lose its 5 pixels on one side, and completely fills the sides when flipped horizontally. I need the 5 pixel buffer to exist in all orientations. Is there any way I can tweak the way auto resize works to make this happen?
My code:
[newsfeed setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
Also, I have dragged one of the many views in from storyboard, and that one does not respond to the code above. How can I make it auto resize?
When you also specify that the top and bottom margin are flexible, you in effect say that the left and right margins are fixed. Try this:
[newsfeed setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin];
As others have commented, this is more easily done in Interface Builder with springs and struts:

iOS - UIAutoresizingMask margin : why do I need to set both sides?

My question may appear strange, but with an example it's easier to understand :
I have, let's say an UIButton, that I create and then :
// [...] Create button, add it to view
myButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
If I don't specify UIViewAutoresizingFlexibleRightMargin, my component will not be at the right x-ratio on the screen. Why ? I specified left margin, so my element should be at the good position when I rotate the device... Don't understand the need of the right margin.
When you use both flexible margins, a change in width will be split between the two margins. This is commonly used to keep a view centered.
When you use just one flexible margin, a change in width will all be applied to the one flexible margin. This means the other margin stays the same, no matter how the width changes.

Resources