AutoLayout with Scrollview and UITextView - ios

So I have a UIViewController with a bunch of IBOutlet's elements placed on a UIScrollView(ContentView). All are using Auto Layout and are working perfect except for the UITextView. Due to its position I cannot figure out what constraints to add to the bottom of the UITextView so the scroll view will notice it's full size depending on the text. Currently the UITextView is underneath/off the view.
This is how the view is composed.
Can't figure out the last constraint for the UITextview
The constraints on the UITextView are as follows:
Trailing Space to: Superview
(Equals: 8)
Leading Space to: SuperView
(Equals: 9)
Top Space to: MapView
(Equals: 70)
These constraints are exactly the way I want the UITextView positioned. It's just the bottom constraint I can't figure out so that the content size is of UIScrollView big enough for the UITextView.
If there's anymore information I need to provide please let me know. I've been stuck with this the past few days.

First make sure "Scrolling Enabled" of your UITextView is disable then
add five constraints(leading, trailing, top, bottom, height) on UITextView and add an IBOutlet on the view controller for the UITextView height constraint. Finally just change the UITextView height constraint programmatically.

Related

Reverse scrollview height controlled by stack view in storyboard

My Goal
To make a reverse scroll view that changes height with the height of the vertical stack (the contents of which will be controlled programatically)
What I have tried
Setting the stack view, Scroll view and content view the same heights. I am not sure how to change the simulated size of the view controller with it
Note: I am using Storyboard not swift UI, I have researched this and all I can find are tutorials for how to do this in SwiftUI
I wanted it to be controlled by the height of the stack view, so it does not scroll when there isn't anything to scroll to, if this is wrong please correct me and give me some guidance
The ViewController now:
Can anyone help?
If I understand your question correctly, I had a similar issue recently.
My solution was:
Fully constrain the UIScrollview within the superview
Place a UIView inside the UIScrollView. Align the UIView's leading and trailing constraints to the UIScrollView's content layout guide AND frame layout guide ( =0, or whatever margin you need). Align the UIView's top and bottom constraints to the UIScrollView's content layout guide ( =0 ). Constrain the UIView's height to be equal to the height of the UIScrollView's frame layout guide with a priority of 500 (make sure the multiplier is 1 as Autolayout might set it to something else). These constraints should be added by control dragging from the UIView to the UIScrollView's layout guides within the document outline (I had problems if I didn't add them this way). This fixes the widths, but if the UIView's height needs to expand then the equal height constraint can break allowing it to grow outside the UIScrollView's frame, triggering scrolling.
Place your UIStackView inside the UIView. Align the UIStackView leading and trailing constraints to the superview (the UIView), or use a horizontally centred within superview constraint. Constrain the UIStackView to be vertically centred within the superview (again, the UIView). Align the bottom constraint of the UIStackView to be >=0 relative to the superview (UIView). Thus, when the UIStackView is smaller than the UIView (and UIScrollView) it remains centred and doesn't scroll. As soon as the UIStackView (and UIView) exceeds the size of the UIScrollView, the >=0 constraint between UIStackView and UIView bottom takes precedence over the equal height constraint between the UIView and UIScrollView frame layout guide, forcing scrolling.
In step 3, I think you might be better served by aligning the top of the UIStackView to the top of the UIView, rather than having the UIStackView vertically centred. The bottom constraint should still be >=0. I didn't try this myself but it should still work.
If you need the UIScrollView itself to increase in size, then pin its top and bottom within the superview to the minimum size you want it to be, with a low priority such as 250, then add >= constraints to fix the outer limit of where you want it to be. For example, Constrain the bottom of the UIScrollView to be =100 from the bottom safe area guide with a priority of 250, then constrain it to also be >= 25 from the bottom safe area with the default priority of 1000. In this case the first constraint to break should be the bottom of the UIScrollView which will allow the UIScrollView to grow until it hits the bottom >=25 constraint, at which point the UIView to UIScrollView_frame_layout_guide equal height constraint will break triggering scrolling.
I hope that makes sense (and that I haven't missed anything)!
PS I also ran into a problem with the UIStackView contents (programatically defined in my case) resizing in odd ways which seemed to be fixed by changing content mode from "Scale to Fill" to "Redraw". I set distribution to "Fill Equally" or "Fill Proportionally" depending on the look I wanted (I had two such views).

Only scroll UIScrollView, if the label in it is bigger than the View respectively

I have a little problem with the UIScrollView. It scrolls way to far. Is it possible to enable it only, if the label in it is bigger than the ScrollView?
Pictures (sorry, they are quite huge):
The Label, that is on the ScrollView, is in the ScrollView
You should try using a UITextView instead of a scrollview. It looks like you only need text. A textview does NOT have to be editable. You can disable the editable check box in the storyboard. Take a look at my screenshot.
If you do want the scrollview method to work, you will have to add a bottom constraint to the label in your scrollview. It will tell the content view of your scrollview the size of the content within the scrollview.
The easiest way this could be done is through the Storyboard (auto-layout enabled).
The main idea is to wrap your views (Labels) inside the UIScrollView with a UIView instead of directly inside the UIScrollView, then you need to set the constraints of the UIView to match the UIScrollView from all sides and add a height and width constraints equaling the UIScrollView. The height constraints priority should be lowered (lets say to 750 instead of 1000) so it will allow the scrollView to stretch when needed and the UILabel's button constraint should be set to greater or equal to allow the UILabel to take it's size and "push" the UIView when it needs to.
Last but not least, you need to lower the vertical content hugging priorityof the UIScrollView and the UIView to 249 and raise the vertical content compression resistance of the UILabel to 751.
Here is a full working example

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:

How do you set constraints for scrollview that doesn't occupy the whole parent view

I'm trying to build UI similar to that of ios photo gallery : Navigation view controller with a scrollview occupying 80% height and 100% width of the parent's view and the collection view controller occupying the rest of the height and 100% width. So here's how it looks like :
The blue area is scrollview and its content view. The bottom part is a collection view which suppose to behave like a carousel. You can see the constraints that I have set in the following screenshot :
:
I want to set the scrollview height so that it only occupies 80% of the parent view estate and the collection view occupies the rest. However, I can't seem to resolve scrollview constraint issues such as autolayout not able to resolve height/y position of scrollview. As you can see in the above pic, I tried setting the height of the scrollview to 50% of the parent view but the autolayout still complains about not being able to resolve height. If I let interface builder resolve the issue, it just adds spacing to the content view inside scrollview and pushes it down as a result. You can see that in the following screenshots.
Your view heirarchy is correctly setup so thats quite nice and you are on the right track of what constraints to add. I'm going to write all the constraints starting from step 1.
To your UIScrollView add a top, leading and trailing constraint to the superView. Also add a equal height constraint between your UIScrollView and the superView and set the multiplier to 0.8.
Now add your UICollectionView below the UIScrollView and give it a leading, trailing and bottom to the superView. Also add a vertical spacing between the UICollectionView and UIScrollView.
Now add for the contentView inside the UIScrollView. Add a leading, top, bottom and trailing for the contentView to UIScrollView. As soon as you do this, the constraints will break and Xcode will complain. Now what you need to do more is add a equal height and width constraint between the UIScrollView and contentView. Set the priority of this equal height constraint (assuming you want vertical scroll) to something like 250, so that it breaks when the content inside the UIScrollView becomes too large to be displayed completely.
Now as far as that extra spacing issue is concerned. What you need to do is, select the UIViewController that has your UIScrollVIew and then select the attributes inspector for this UIViewController and uncheck the adjust scroll view insets option. For a screenshot, check this.
As i see from above do the following.
Add leading, trailing and top constraint to scrollview.
Add height constraint i.e drag from scrollview to superview and add equal width, in equal width constraint change the multiple factor to 0.8.
Add leading trailing, bottom constraint to collection view with respect to superview and vertical space constraint with respect to scrollview.

Auto resize UIView based on multi line UILabel

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!

Resources