Moving item after constraint has been applied - ios

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.

Related

UILabel height depending on font size

I am using a UILabel in a UITableViewCell to display a title. Normally the text is not too long and therefore the font size can be large. Notice how the text fills the height of theUILabel like normal.
However, when there is a larger title, I want the UILabel height to reduce to accommodate the smaller font size and not leave a blank gap in its place. Currently, my configuration produces this effect.
I am using constraints in my storyboard and have deliberately not set a fixed height constraint. Here are the relevant constraints added:
I may have made a rookie error in my configuration as I can't remember this effect happening before, but it is giving me real headaches (and a bad looking UI).
When UILabel is set to auto-adjust font size to fit, it does NOT auto-adjust the height of itself.
You have a couple options:
set Baseline to Align Centers, and just accept that you will have top and bottom padding
use code to calculate the "scaled font size" and update the font size of the label
Remove either the Top Space or Bottom Space constraints (depending on where you want the label to be anchored).
This will cause the label to automatically use fit itself to the text size.
Try this and see, it should work according to your need:
Set Top and Bottom constraints attribute Greater Than or Equal To and add horizontal center (Alight Center Y to superview) and show in this image.

adding nearest neighbour constraints to a NStextfield causes it to shrink to the size of the text

Edit: I found the correct solution and will include it at the bottom of the question
I have a textfield. I constrain the textfield to nearest neighbour, which is in this case the view and when i do this, height for the textfield goes out of my control and matches the size of the text exactly. How can I constrain the text box to nearest neighbour without the text box automatically resizing. Below is an image that shows my constraints and the orange outline of what the textfield wishes to resize to. It also shows that the view will shrink to an expected height of 62 aka the size of the text box.
I would add, that when i checked the constraints in inspector, i found that the text box was not always set to first items. when I made the text box the first item in all constraints the width became editable.
Answer:
1) The secret to adding constraints to a text box it to put content hugging as a low priority eg. 250. Look at the above picture and you can see content hugging vertically is at 750 or high priority while content hugging horizontally is at low priority(=250). Therefore i am able to constrain to nearest neighbor for the width which is at low priority but not for the height which is at high priority.
For more info check this documentation
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithConstraintsinInterfaceBuidler.html#//apple_ref/doc/uid/TP40010853-CH10-SW2
2) each constraint has a first and second item in the inspector. The second item gets its attributes(eg. size) from the first. double click on the contraints in the size inspector as pictured above to inspect the constraint more closely
The layout engine does not know what size you want the parent view (your view controller in this case), so it takes the intrinsic content size of the textfield.
Do you want the textfield to be exactly as big as it needs to be? Then don't touch it, your textfield will resize to contain the text, using your constraints to place itself.
Do you want your view controller to have a certain size? (e.g. if you want a specific background image to fit) Then you might want to consider adding constraints to your parent view so that it keeps a certain size or aspect ratio.
I will suggest to remove existing constraints, and add vertically and horizontally center constraints.

Stop UITextField from expanding horizontally

I have a UITextField positioned in a view next to a button. It has a trailing constraint of 8 to the button (which has a trailing constraint of 8 to the superview) and when I type long text in it, it simply scrolls along, which is I want. However, in order to retain the text typed in the field if the view is switched to another one (it's in a tab controller), I save the text in a holder variable and when it switches back to that view, I set the text in the field to the saved text.
The problem is that this causes the field to expand horizontally if the text is long enough, sometimes pushing the button off-screen, even with the trailing 8 constraint. I have tried to save the original frame of the field in a holder variable, and then after setting the text, set the frame to the saved original frame like so:
fieldFrame = messageField.frame
println(messageField.frame.width)
messageField.text = holderMessage
println(messageField.frame.width)
messageField.frame = fieldFrame
However, the field still expands, and it printed out 502.0 twice. My current thought is that the frame hasn't registered the change in width after the setting of the text in time for the println, but I'm not sure if this is correct.
Also, I've read some similar questions that suggested using a width constraint. If I use a less than or equal to width constraint on the field, will it still expand if on a device that's thinner? That is to say, since I'm currently using an any width and any height storyboard, it's wider than, say, an iPhone 6. So if I set a less than or equal to width constraint on the current width of the field, it seems possible that the field can still expand on a smaller device and not break that constraint.
Is there a better way to do such a width constraint? If not, how else can I keep the field from expanding and pushing the button offscreen?
Here's the problem. The text field has a tendency to size itself horizontally to its contents. The button has a tendency to size itself horizontally to its contents. Thus you have an ambiguity: those tendencies have the same priority, so the runtime doesn't know which one to collapse as the text field's text gets too long.
The solution is to adjust those priorities. You must lower the horizontal compression and hugging priorities for the text field - one point lower should be sufficient. Now the button will have a stronger tendency to match its own size to its contents, and the text field will clip its contents.
You can also lower the Content Compression Resistance programmatically (this also works if you are using a UIViewRepresentable in SwiftUi):
uiTextField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
For more info on this topic please refer to:
https://medium.com/#dineshk1389/content-hugging-and-compression-resistance-in-ios-35a0e8f19118
Selecting the Text view, then within Size inspector:
1) Set "Layout Margins" to "Fixed".
2) Under "Content Compression Resistance Priority", set the "Horizontal" to be "Low (250)".

UILabel writing over another UILabel when to long text

I stumbled on to a problem to which i am not sure how to fix.
As you can see here the Label where the name is supposed to be,(i get the name from a user input meaning its dynamic). If it is written to long, it just writes over the other labels.
Also in the storyboard the UILabels are not set to be longer than another label. Each label ends right before the other one starts.
FYI i have already used constraints to make them have the position that they should. Any suggestions?
EDIT1
Also the name label to the right(the last cell) there should be more text but it is not visible. As if it is continuing to write over the edge?
EDIT2
Here is an image showing the constraints i have on the label and some other useful info.
EDIT3
Here is an image after i tried to remove the constraints and i even made the label so small but the results are still the same. The text is going all the way to the score label
Your constraint of the label width is set to 221, so its width will be 221 no matter what screen it is on. Thats why on simulator it behaves like this(different screen size than storyboard). Your constraints are wrong, thats why its overlapping, your label is bigger than its suppose to be.
EDIT
Set score label width constraint, set score label center horizontally and vertically in superview. Now right text label attach to this score label and superview, and left text label attach to this score label and time label, also set this time label width contraint so it doesnt change, its a small text and u know the size of it all the time, so you can keep it at width like 30. Now you are done, your text labels are adjusting their size according to screen.
If its still not working, check your superview has set constraint to adjust to screen size, as well as tableview.

UILabel alignment to other UILabels

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.

Resources