UILabel alignment to other UILabels - ios

I have a cell prototype that i'm trying to add two labels to. I have the two labels right next to each other, but the size of the labels are dynamic, so I want the second label to be able to shift depending on the size of the first label.
Basically, I want there to be a fixed gap between the two labels, but the two labels' sizes are dynamic.
How do I do that?
EDIT:
Actually I found out how to do it via Storyboard. If you select the two labels you want to have a fixed gap between, just command select both of them and then go to the corner of storyboard and click the pin menu, which is that little 'H' looking thing in the group of buttons near zoom in/zoom out in the bottom right corner of the storyboard screen.

Get the label size by this method:
- (CGSize)sizeWithFont:(UIFont *)font
https://developer.apple.com/library/ios/#documentation/UIKit/Reference/NSString_UIKit_Additions/Reference/Reference.html.
Then set label's textAlignment to NSTextAlignmentLeft and NSTextAlignmentRight, and set frames by the string size and other offset.

UIView -sizeThatFits: and -sizeToFit will allow you to manually calculate a position for the second label. This is slightly more accurate than using the NSString method, as there's more to a UILabel than just the text — this will respect content insets, etc.

Related

Moving item after constraint has been applied

I have a table cell, and it has a label (which has the username), and a button (which takes to a location). There are constraints set to be the same on the y axis (center vertically to each other) and 5 px trailing/leading to each other. Works great. What doesnt work great, is if the label text is extremely long. It will push the text off the screen. How do I make the button go down to below the label? Similar to float in css?
^^This is the cell, and as you can see it goes off the screen. I need "San Francisco, CA" to be pushed below the label "#VeryReallyReallyLongUsername". I know you can do dynamic cell resizing using AutomaticDimension...
For that you should manage many thing programmatically. You can take outlet of constraint by ctrl + dragging from constraint to class file.
Then you can manipulate it's constant.
So if you want to let your button goes down when text is large then you can take outlet of top constraint of button and then increase it's constant by some pixels that you want and do same for label take outlet of it's width constraint and increase it's constant by some pixels that you want to increase width.
Second thing if you don't want to manage stuff like mentioned above then you can use multi line label. just set the numberOfLines property of your label to 0.
So if text size will be large then label distributes in two line or three line.
Or you can set Autoshrink property from attribute inspector from IB(story board) to minimum font size and set minimum font size with it. so if text is larger then it reduce font size that it fits exactly to label but not reduce more than that minimum size that we have set.
Hope this will help :)
Not easily. It may be possible to set up constraints which would do this, but I wouldn't know where to start.
I would pick another option such as having the label truncate the long value (it will put ... at the end), or to have the label scale the text smaller, or to have the label grow vertically and wrap the text.

UITableView cell vertical centering of label when another is empty

I have a UITableViewCell that contains two labels positioned vertically one on top of another, and I am using AutoLayout.
The cell works (and looks) fine when both labels have some text.
Sometimes, though, the top label does not contain any text, and in this case I would the cell to have the same height, but the bottom label to be centered vertically. Is it possible to do it with AutoLayout without modifying the constraints at run time?
I don't believe this can be accomplished without modifying something at run time. I see a few options if you'd like to do this without changing constraints programmatically, some messier than others:
First option, you could set three labels in the cell. Two labels that are stacked vertically and one that covers the whole cell vertically, fully overlapping both other labels. At runtime you can determine if the bottom label shouldn't contain text and then set the overlapping top label with the text you would have previously set on the top vertically stacked label.
Second option, you could utilize a label that has the height of both labels you currently have. Set this new (2x height) label to allow for 2 lines (can be done in InterfaceBuilder side options). Then at runtime interpolate the label.text attribute with both label's text. Put a new line character in between the labels if the second label has text. It would look something like this
In Swift:
my2xLabel.text = "\(firstLabelString) \n \(secondLabelString)"
In Obj-C:
my2xLabel.text = [NSString stringWithFormat:#"%# \n %#", firstLabelString, secondLabelString];
All of this being said, modifying the constraints at runtime may be a less hacky way to achieve this formatting.
Make two prototype cells then. One will be the one you have right now, the other would contain only one label but centred vertically. Check if the text would be empty, return the cell with the vertically centred label. Otherwise, return the other cell.

Place Text in Top part of UIlabel

I have a UILabel that covers most of the view. When I place text in the label, the text is center in the middle of the label. I have tried everything by playing around with the options in the attributes inspector, however the text wont start in the top area of the label, instead it appears in the middle of the label.
Is there any way to places the text in the top part of the label??
(If someones is wondering, yes I want the UILabel to cover most of the view because some texts are longer then others, and some are shorter, and I would prefer the text to be placed on the top part and not the middle of the UIlLabel.)
UILabel has an intrinsicContentSize matching the text contents. If you don't constrain the height, then it will automatically adjust. So you don't need to make it cover the entire view.
Instead, tag it onto the top with a fixed distance. Specify the bottom distance with greater-than-or-equal. This way the label can grow until it reaches the lower limit and then the text will begin to be truncated.

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.

Custom/Dynamic label width using auto layout

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.

Resources