UIScrollView with Autolayout Ambigous height - ios

I've read a lot of manuals/tutorials on ScrollViews with vertical scrolling, but havent figured out how to solve my problem so far.
You can see my ScrollView visual plan here:
ScrollView plan
The most helpful answer was here, on StackOverflow:
https://stackoverflow.com/a/30282707/3718319
Accodring to it, I made the following:
My ScrollView(makred red on my screenshot) has got 0,0,0,0 constraints and equal width to ViewController's view. Inside my ScrollView I made a ContentView(makred orange on my screenshot), that contains (makred green on my screenshot):
1) ImageView with constant height and pinned top/left/right to ContentView.
2) View with constant height and pinned top to ImageView, left/right to ContentView.
3) View with constant height and pinned top to the View above it, left/right to ContentView.
4) TextView pinned top to the View above it, left/right to the ContentView and pinned bottom to the ContentView.
So, all the vertical constraints are set, and my scrollable content height should change according to height of text view. That's what is my goal.
But I got error from storyboard, telling: Need constraints for: Y position or height.
Could you please help me solve this problem?
Thanks!

The reason storyboard throws those warning is because it cannot calculate the scroll view's content size. With your first set of constraint in content view, it has an ambiguous height.
lets say for example that you set each height constraint to 100 and pinned constraint have 20 space value, the frame for each subview inside content view would be like this:
ImageView (20, 20, view.Width, 100)
View (20, 140, view.Width, 100)
View (20, 260, view.Width, 100)
TextView (20, 380, view.Width, ??)
since your textView have top and bottom constraint, the height of it will vary, and content view's height will also vary according to textView height.
However, textView also have scroll feature, which will make it difficult to calculate its height related to content view without additional constraint.
Since you disable its scroll function inside textView, storyboard no longer have any difficulty calculating each subview frame which is why the warning is gone.
optionally, you can enable textView's scroll function and giving height constraint to it which will give enough info for storyboard to calculate each subview frame.

I've just figured out, that I had to uncheck "Enable scrolling" on my textfield. That makes sense.
I've already tried it before, but it didn't help me before I've made this storyboard ViewController from a scratch.

Related

UIScrollView jumps when content has almost the same size as screen

I have an UIScrollView that "jumps" to the end of the content on touch when the content has almost the same size as the screen. This does not happen when the content is significantly smaller or larger (see video).
I assume this has something to do with the safe area as this problem does not appear when the ScrollView is smaller than the safe area.
iPhone 13 Pro Max / Screen width: 926pt / Safe Area width: 838pt
Content Width: 850pt -> Jumping on touch ❌
Content Width: 1000pt -> Normal scrolling ✅
Content Width: 600pt -> No scrolling ✅
UIScrollView Setup
View -> ScrollView (white) -> ContentView (grey) -> BlueView (blue)
I got a ScrollView that is the same size as the screen (leading, trailing, top, bottom constraints to Superview = 0). Inside is a ContentView (leading, trailing, top, bottom constraints to ScrollView = 0). It also has constraints to be the equal with and height of the highest level view of the ViewController (with a priority of 250). This ContentView wraps around the BlueView which defines its size. It's basically setup as described here: https://medium.com/#pradeep_chauhan/how-to-configure-a-uiscrollview-with-auto-layout-in-interface-builder-218dcb4022d7
As I wrote before, I assume this could have something to do with the safe area and me having some incorrectly setup contraints for the Scroll View, but I can't figure out where I got it wrong. Thanks!
Please don't give a fixed width of contentView & blueView. Just give a leading & trailing constraint of scrollView in respect to superview. Make scrollView Horizontally centred.
Try with above changes. Hope it will work.
Solution 1:Please Off Scrollview's Bounce On Scroll
Solution 2:Take A Parent View Behind
take parent view means firstOfAll Take ViewController > Take A View On It > Then Take ScrollView (Give Equal Width To View)

Autoresize container height created from nib if subview (UILabel) height changed

I want to resize container view (in my case AnnotationCallOut) when the text in UIlabel (named textLabel) becomes too large.
Container view has defined height and width (size: Freeform, width:200, height: 100).
In this picture you can see that I have created constraints between elements:
But when I add a large text into textLabel, it simply goes over:
How to autoresize container view in this case?
Thanks.
You need to add a bottom constraint between the frame and the bottom label, without this the autolayout doesn't know what to do with the height of the frame!
Add the constraints, titleLabel set Top, Left, Right and fixed height constraints example is given below,
then SecondLabel set the Top, Left, Right, Bottom constraints to be set, if you will get exact output.
hope its helpful

UIScrollview is not scrolling beyond UIView height even though UIView frame is increased

I am trying to create a screen where scrolling is required in iphone 3.5 inch screen . I have attached images which contain the configuration of uiviewcontroller , uiscrollview , uiview . The problem is eventhough the height seems to increase , when i run iPhone 4s , some part of scroll is hidden beyond the UIView (Although uiview height shows 700 when i print the height in console) . What might be the problem ? Please help me ?
You have constraints that have negative values. On the last screenshot, which I assume are the constraints from the view inside the scrollView, the bottom offset to the superview is -400.
I think this is why you don't see the entire view because the bottom offset is negative. Try setting this value to 0, this should fix it.
If this does not fix your problem, maybe you could specify for which view the constraints from the images are.
Let me know how it goes! Good luck!
When you work with UIScrollView and AutoLayout it's always tricky.
You have to add all your subviews to one UIView and add that view to UIScrollView.
Autolayout Constraints you need:
For UIScrollView:
Left to Superview
Right to Superview
Top to Superview
Right to superview
For Inner View of UIScrollView (i.e The only view inside ScrollView):
Width & Heigh
Left, Right, Top and Bottom constraint to Superview (i.e. ScrollView)
Also add Horizontal Centre to Superview.
And it'll work like charm (Works every time for me at least:)
The contentSize must be larger than the scrollview's frame for there to be anything to scroll. :)
In this case, they're both (600, 1300) so change your scrollView's height to (320,480)
It's a bit confusing, but as Yuvrajsinh told you, you need to set the auto layout constraints for your scroll view to its 4 sides to the superview. Then do the same with the content of the scrollView, and the most important: Set a fixed/not related with scrollview height and width for the content
Thanks for the information and suggestions . Now it is working correctly . What i did is
set scroll view top ,left , right , bottom aligned to superview
Set content view of scroll view to top , left , right , bottom aligned to scrollview
set the content view of the scroll view to "Equal Heights" and "Equal widths" to the top superview.
Then i set the equal height constraint to have low priority of 250
Now i can scroll whenever required based on the size of the phone screen :)

UIScrollView content size fixed to 600x600(Main.storyboard size)

I've been facing this issue from past 2 weeks and not yet got a solution.
I'm using UIScrollview in my application where the problem exists.
Generally in my app, there is dynamic text and images with different sizes will come from webservices. For example, imagine the Facebook Newsfeed. My application is similar to the Facebook newsfeed. Sometimes, there will be only text, sometimes there will be text and images. And comments for that post.
As i've seen in many links, the heirrarchy i'm following is SuperView-->UIScrollView-->Content View and the elements are placed in that content view. I'm assigning the constraints from the elements in the contentview to the Superview (ContentView --- constraints -- SuperView). When the content in the view exceeds the size of the superview, it has to scroll. But the scrollview content size is limited to the size of 600x600 i.e., in main.storyboard, when we design for W any x H any size. I've seen many tutorials and searched many sites. But following them gives me no luck.
Any help is appreciable.
Here is how to set up a scrollView in Interface Builder from scratch that works with Auto Layout.
Start with a new ViewController. Drag out a scrollView such that it fills the view. Untick Constrain to margins and constrain the left, top, right, and bottom edges of this scrollView to the left, top, right, and bottom of its superview with offsets of 0. This allows the scollView to fill the screen on any device in any orientation. You can make your scrollView take up less of the screen if you like, just make sure it is fully contrained.
Add a view to your scrollView. This should be the only top level view on your scrollView and it will serve as your contentView.
Constrain the left, top, right, and bottom edges of this contentView to the left, top, right, and bottom of the scrollView with offsets of 0. At this point, you will see warnings about ambiguous content size. That is because you haven't told it yet how big your content view will be.
To size the contentView, add width and height constraints to the contentView. If you want it to scroll, the width and height must be larger than the width and height of the scrollView itself. If you only want to scroll vertically, set the width of the contentView to be equal to the width of the scrollView. To do this, in the Document Outline view, control-drag from the contentView to the scrollView and select Equal Widths from the pop up.
If you want to be able to change the height of your contentView from code (to account for dynamic content), first create a height constraint for your contentView by control-dragging within the contentView and selecting Height from the pop up. Create an IBOutlet to the height constraint by control-dragging from the height constraint (found in the Document Outline view) to your ViewController's code. Give the outlet a name like scrollViewHeight then set the height with a value like scrollViewHeight.constant = 2000 when you need to change the scrollView's height.
Simply add your UIScrollView to your UIViewController's view in the storyboard and add the appropriate constraints in the interface builder.
Then, build your content view in the code and give it any frame you want, now start adding your controls to this content view and calculate the size of each one (especially the height), and at the end you have the total height of your controls.
Now set the frame of the content view to match that height and add it as a sub view to your scroll view, then set the content size in the code like this:
_scrollView.contentSize = contentView.frame.size;
Another note, do this changes to the sizes in the viewDidLayoutSubviews to avoid any problems with different screen sizes but be careful, this event is called many times so have a BOOL or something to ensure that the code that creates the view and add it to the scroll view is executed once, e.g. like this
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
if (! built) {
// Do everything I explained above here
built = YES;
[self.view layoutSubviews];
}
}

UIScrollView in Storyboard not working with iOS 8 Size Classes and Autolayout

So I'm trying to create a UIScrollView only in storyboard that allows me to add scrolling labels for more than the height of the VC. Here's what I did:
Created UIScrollView that took up the size of the any width any height VC
Made constraints 0 for spacing to nearest neighbor on top, bottom, left, and right
Created a view that is a subView of the UIScrollView with the same width as the any width any height VC but height of 1500 (because I only want it to scroll vertically).
Set constraints to nearest neighbor as 0 for ONLY left, top, and right and set the height constraint as 1500.
I put a label at the top of the subView and at the bottom
When I run the app on an iPhone 6, does not scroll vertically as I want it to. Any ideas why this is not working? Thanks in advance.
To obtain the scroll you have to pin the sub view (the "content view") to the top, left, bottom and right of the scrollview.
In addition you have to give it (to the "content view") an explicit (=not related to the scroll view) height and width because these are used by the scrollview to calculate its content size.
In your case set the width equal to the VC main view width and the height to 1500.
When width or height are bigger than the scrollview size, it will scroll.
Scroll view constraints (pinned to main view)
Content view (pinned to scrollview + height 1500, width=mainview width) + label constraints (as an example: 20 20 from content view top left)
For an easier visualisation, I created a video on how to do that.
Video on how to create a vertical-only scrollview in iOS
Have you set the contentsize bigger than the screen itself? In your case, just bigger in height.
As Apple Documentation says:
"You must set the contentSize property to the size of the scrollable content. This specifies the size of the scrollable area."
The only solution is add constraints to the right and bottom of the bottom subview of scroll view's child view.
Also check if all the views from top to bottom have got proper constraints along with height.
For the scroll view ' s wrapper view add equal width and equal height constraint to its superview.

Resources