Auto resize UIView based on multi line UILabel - ios

Problem:
I have a custom view with a multi-line UILabel (se picture below).
This custom view is then added to a screen in my storyboard (se picture below).
This works great. The problem is that the multi-line label will change dynamically a few times under execution, and then the blue UIView box won't fit. It's also a problem with smaller/bigger screen size.
Question: So how do I get the UIView to automatically resize in height according to the height of the UILabel? Is it possible to do through Interface Builder and Autolayout? (not nececery, but most of my other settings are done through IB)
Let me know if there is more details needed.

As long as you make sure that labels in your custom view are pinned to all sides (Title Label pinned to: Leading, Top, Trailing of the superview and Bottom to Content Label; Content Label pinned to: Leading, Bottom, Trailing of the superview and Top to Title Label) you will have your superview change it's height according to the content.
Also, note that your superview won't need a height constraint, just pinning it to the Leading, Bottom and Trailing sides should be sufficient.
I had almost identical view in one of my apps. What I would do to make sure the height changes according to update is this:
customView.setNeedsLayout()
customView.layoutIfNeeded()
You can also wrap this code in UIView.animate(withDuration: ...) block
Cheers!

Related

iOS UIScrollView Issues

I am unable to get a scrollview to scroll if I use a view in the scroll view. I followed the example https://useyourloaf.com/blog/scroll-view-layouts-with-interface-builder/ , which used a stacked view in a scroll view. When I follow this example and use a stack view, it works. My UI requires a view because of the layout I need for the controls.
I have a sample project at: https://github.com/eloew/ScrollViewTest which illustrates the problem. I have used the storyboard so no code to post here.
Is it possible to use a view in a scrollview?
#eloew You are almost done. You just need to adjust few things.
Your view width have to equal with scrollView width.
Put the height and bottom constant of Second textField/Label.
Done
The procedure you are using is correct but it is sometimes tricky to setup constraints. Your view needs to have either implicit or explicit width and height. Then it needs to be inserted into scroll view and have all 4 border constraints setup.
Looking at your project you have missed a few constraints. To debug a view like that it is easiest to first set it up outside the scroll view. Take your view outside it and setup leading and top constraints to it's superview. Now modify your constraints until you see a desired result.
For your specific case I used:
View width equals to superview width
First label leading and top are pinned to superview leading and top
First text field leading to First label trailing
First text field trailing to Superview trailing
First text field center vertically to First label
Outlet label leading to Superview
Outlet label trailing to Superview
Outlet label top to First label bottom
Second label leading to Superview leading
Second label top to Outlet label bottom
Second text field leading to Second label trailing
Second text field trailing to Superview trailing
Second text field center vertically to Second label
Second label bottom to Superview bottom
After all these are set I have a nicely layout view without a scroll view. There should be no errors visible.
Now add a scroll view. Pin it to leading, trailing, top and bottom. Then drag your view inside your scroll view and this view to scrollview leading, trailing, top and bottom and set equal width between your view and your scrollview. That should be it.
Short answer is yes it is possible. Simply add a view as a subview in your scroll view and set its constraints.
Apple's documentation
It is simple enough task, you can even find examples here on SO.

How do I make the UIView superview of a UILabel fit the intrinsic height of the UILabel using the storyboard only?

I got a UIView whose child is a UILabel. I then aligned the left, top, right, and bottom of the UILabel to that of its superview (the UIView) using constraints.
But what I'm getting is a UILabel that matches the height of its superview but not its intrinsic height (smaller or larger than its text content depending on the size of the UIView). What I expect is for the UIView to resize itself to fit exactly the height of the UILabel.
So how do I do this using only the interface builder?
In order to make the UILabel keep its size and force the outer view to resize you can update the values for Content Hugging Priority to 1000 (a.k.a. Required). This can be done in the measurements panel when selecting the label in Interface Builder.
I think they are set as a default to 750.
This should (if there is nothing else causing the change) make the label take its intrinsic content size and force its superview to conform to that size also.
Align top, trailing, bottom and leading of UILabel with UIView (add constraints).
Remove height and bottom constraints from UIView if any.
If the content is large, you probably need to wrap UILabel into a UIScrollView in place of UIView. and add a bottom constraint to UIScrollView
Content Hugging Priority of UILabel (251) is more than that of UIView (250) by default. Verify this
It's super easy using auto-layout. Just, follow these steps
1 - Drag a UIView and align it vertically and horizontallyin centre.
2 - Now drag UILabel into the UIView and align the label also horizontally and vertically in centre.Now, the IB aligns the label at the centre WRT to the superview and not the UIView.So, change that in the size-inspector section.
3 - Once you have done that and all red lines are removed, select both the label and the UIView together using the command key.
4 - Now, give them constraints as follows
leading = 0, trailing = 0 and select the equal width and equal height.
There you are done.If you wanna test that the UIView size is respective to the label's content, try increasing the label's font to a bigger size and you will see that the size of the view will be the same as the size of the label.
There , you are done :-D. Hope, this was helpful.
If someone is experiencing this issue, while:
Having 2 labels inside the UIView
Doing everything what was suggested here
In my case, I set Vertical Content Hugging Priority of BOTH UILabels to 1000. Then one of the labels had a different font. (ie. one label was supposed to be smaller than the other one)
The height was being ambiguous, because both labels were trying to force their height on the superview. Once I lowered the priority on the smaller label, everything worked fine.

UIScrollView Autolayout height not setting on dynamic content

I have two labels that are inside a stack view that is encapsulated in a scroll view. The layout structure is like the following:
The layout looks like so in the interface builder. (This is the view with the contentView selected)
The Content Stack View is pinned to the contentView's via top, leading, trailing with 8pt on each.
The labels are set at runtime and can be quite tall. This cuts off the text and causes the scroll view to not be scrollable. (Cuts off at bottom)
I've went through a few other similar questions on here but was unable to find a solution to mine.
Some are resources I went through I looked at were Mokagio, and Natasha.
I have been on this for over a day now and am completely stumped.
How does the Scroll View's content size become scrollable from the generated content?
Please follow below steps:
Add UIView into UIScrollView and then add both UILabel into UIView.
Set top, bottom, leading, trailing constraints to UIScrollView and UIView
For both UILabel set top, leading, trailing, bottom, width, and height constraints.
lastly edit height constraints to set - priority High(750), select >= from constants dropdown for both UILabel
IMPORTANT: set UILabel's number of lines to 0
Please see below screenshot for UIlabel constraints:

Multiline UILabel with UIScrollview using autolayout

I read many post of contentview in scrollview,but the problem is slightly different.check out the image
and i have following hierarchy
Here the label is multiline label and its fill up with too many content size.
so, the problem is
1. according to the lines of the label, height of label changes and
2. accoring to height of label, contentview height changes.
so, that it scrolls. and i want this things to be done with autolayout.
And one thing i want to mention is , i'm using ios 8.1 and xcode 6.1
The thing that you can use for your UILabel is -> Select your Label and go to Attributes Inspector and find Autoshrink set it as Minimum font size then you may describe your minimum font size.
For addition to your view, you may want to use constraints between your label and content view. So I recommend to use this documentation Auto Layout Guide. And if the documentation is too long to read you may read this answer.
You should add constraint to content-view as leading, trailing, top, bottom & equal width & equal height with scrollView. For imageView add constraint as leading, trailing, top & height. For the Label add constraint as leading, trailing, top & bottom, also check that you are setting no of lines to be zero. & For read more button add constraints as height, width, centre horizontally in container & bottom. Don't forget to add bottom constraint to button otherwise your scroll view does not understand its content size & you will get warning as ambiguous content size to scroll view.

Correctly Size UILabel inside UIScrollView using Interface Builder and Autolayout?

I've created a simple view setup in interface builder. Here's how it looks:
The view hierarchy is simply:
view
- scrollView
-- label
The scroll view is shown with grey background anchored to its super view top, leading, trailing, and bottom with constraints of 0.
The label is shown with yellow background and has constraints as shown. Additionally, the label has content hugging priority of 1000 for both horizontal and vertical, and it has content compression resistance priority of 1000 for both horizontal and vertical.
In portrait orientation, the label is sized correctly:
In landscape orientation, however, the label is not sized correctly horizontally (I intended for the label to fill the width of the screen, less constraint insets as shown):
How can I get this label to size correctly horizontally in landscape orientation?
There is one solution for you.
1. Add your UIScrollView to container (UIView) with zero constraints:
2. Add constraints for Label: top, bottom, leading, trailing spaces = 20.
3. Add constraint: label.width = container.width - 40
For this, select label in the view structure tree, tap ctrl and pull
to container. And select Equal Widths.
Then select the created constraint and go to its Utilities and set
the constant value to 40.
You should get the following components:
Run the app, go to landscape and it works!
Hope it is clear. Best Regards.
It's hard to tell which constraint(s) to add/remove in order to get what you want because iOS reserve the right to adjust your constraints whenever it becomes impossible for it to satisfy all your constraints.
I make a blank project with the same view you have (UILabel as subview of UIScrollView) and make some constraints to get the UILabel resized properly on landscape.
A must check though:
Make sure you set the vertical/horizontal spacing constraints from the pin option, as shown below and try to remove unneeded constraints manually.

Resources