Setting the content size of a view inside UIScrollView - ios

I have to lay out a few views in a View Controller which should look like this when run.
Initially the white view should be partially covering the blue view at the bottom like shown in the image. The blue view should stay put while the white view at the bottom can be scrolled over the blue view.
I added the blue view to the main UIView of the view controller. Then added a UIScrollView on top of blue view and added the white view on to the scroll view.
Now I'm getting the dreaded ambigeous content size error. I have pinned the scrollview on all four sides. Then added leading, bottom and trailing constraints to the white view. Then I tried adding a top constraint to the white view but the error still persisted. I also adding a height constraint to the white view to no avail.
It might be dofficult to imagine my setup so I added a demo project here as well.

I set the constraints for you here.
Explanation:
You are getting ambigous content size because your scrollView does not know its content (white view's) width and height.
I added top,width and height constraint to white view. This way your scrollView knows its content width and will scroll only vertically. As for content height - u can change heightContstrait's constant in code, or completely remove height constraint if you use autolayout properly for white view's subviews.

Put the blue view under scrollview. And set scrollviews content inset, to make your white view appear not on top, but with some space. Now on start you get white view a bit over blue, and on scroll it covers blue view. About size errors, scrollview needs to know it’s content size initially. I assume your white view is table view, so set it’s bottom constraint to zero. If you want blue size to change it’s size on scrolling, like it’s avatar or something, it’s a bit different. You should take scrolling events on uiscrolldelegate, and change blue views height accordingly

Make sure you've read (and understand) Apple TN2154: "UIScrollView And Autolayout", which explains the steps required.
Looks like you're not specifying the content size properly.

Related

Autolayout with UIScrollView

I am using autolayout in Xcode and am creating a fairly tall (1300px) ViewController with a uiscrollview to navigate up and down. I made the viewcontroller freeform so its dimensions are [375,1300]. I then incorporated the scrollview, added the content view as well as all the subviews & constrained everything, leaving no constraint errors. At runtime there are no errors, but everything is all smushed into the normal screen size when I intended for it to be very tall (~1300px) and scrollable. Any clue as to what I am doing wrong?
Below is a diagram showing the issue where:
The Outer Black Blox is the ViewController's view
The Inner Black Boxes are subviews
and The Blue Box is what is displayed on the screen
Yes, your correct #Ryan Cocuzzo. I think you need to set sub view priority from 1000 to 250. See below screen shots.
1) Select height constraint of the subview
2)Then go to show to size inspector
3) Now change the priority constraint from 1000 to 250.
4)Finally you get like this
Make sure the following are true:
The 4 content views are subviews of the UIScrollView, not your view controller.
The autolayout constraints on the 4 content views must reference the UIScrollView only, not the view controller's view.
The 4th box cannot have a bottom constraint.
It looks like the 4th box has a constraint to make it's bottom align with the bottom of the view controller's view. This would force the other views to smush up together. The 4th box also cannot have a bottom constraint so that the scrollview can resize itself to encompass it's subviews.

View inside UIStackView is not resizing with AutoLayout

I have this following screen:
All of the views are inside an UIStackView. The yellow view would be circular on runtime. My issue when I run an a smaller iPhone (5S), the light blue view which contains the yellow view, will not get smaller, so the red and blue view from the bottom will shrink. I want these two and the green view to have fixed width and the light blue view to adapt height.
But for some reason it doesn't. I am sure is because of the constraints I set to the yellow view. But I can't figure out which one is the problem.
Here are the yellow view constraints:
The constraints for the other views are:
Green view: height = 64
Red and blue view: height = 50
Much appreciate if someone could take some time to look over this constraints and help me understand how to make the light blue (and yellow) to change height when screen changes.
Did you try lowering the Content Compression Resistance Priority (vertical) for the light blue and yellow views to be less than 750, and the Content Compression Resistance Priority (vertical) for the green, red and blue views to be higher than 750 (maybe even 1000 / required if that's the case?)
UPDATE
I took a look at your project. Actually, the issue doesn't seem to be with your stack views, constraints, or the DailyStatusViewController at all. Instead, the issue looks more related to the MainViewController which is embedding the Daily Status view inside a scroll view. The scroll view is both clipping to bounds, and is placed behind another container view. If you turn off clip to bounds on the scroll view, and move the container view below it to be behind it, you will see your stack views laid out correctly, but were just being clipped.
As to why they were clipped, keep in mind that your out stack view has a required height constraint of 300, while the scroll view it's being embedded in has a height constraint to 45% of the screen height. So on smaller screens, there is less than 300 points available to display the Daily Status view, and so it is being clipped. You probably want to remove the fixed height constraint from your outer stack view and instead constrain it to the edges of the root view.

Gap between main view and scroll view using Auto Layout in navigation controller

I'm experiencing some trouble managing a scroll view embed inside a navigation view controller. I'm using Auto Layout and I'll try to explain the problem the best I can.
I embed a scroll view in the controller's main view and pinned the top, left, bottom and right borders to main view's borders.
I embed a standard UIView inside the scroll view and gave it a fixed height of 800 points. This should act as a container for all my controls (let's name it content view). Then again I pinned its top, left, bottom and right borders to the scroll view's borders. Because the bottom space constraint of scroll view's descendant view was negative, I adjusted it bringing it back to 0.
For the width, I CTRL-dragged from the content view to the main view and added a Equal widths constraint.
Finally, I added an image view and placed it at the top center of my content view adding some further trivial constraint.
The storyboard for the situation I've just depicted is shown above (in the document outline you should see all the constraints I've defined).
My scroll view works, it scrolls fine and the image view is well-centered where it's supposed to be. However, there's a gap between the end of the navigation bar and the start of the scroll view and I can't figure out why. It seems to be as high as the navigation bar, but I have no idea about how to fix it. The image shown below should make you understand what I'm talking about (the content view is highlighted in grey for clarity).
I didn't write a single line of code to achieve this result. I would really appreciate any kind of help and I'm ready to give you all the information you need to help me address the problem.
I think you should uncheck Adjust Scrollview Insets property of your viewcontroller to get rid of this....
you have to uncheck Adjust Scrollview Insets

How to center a bunch of horizontal views in a UIScrollView

I have a UIScrollView that fills the width of the device and it contains several UIViews laid out horizontally. The views all have the same width, so on the iPhone one has to scroll to see all the views, but on the iPad all of the views are visible.
My question is how can I perfectly horizontally center the views on screen? When the available space is large enough to display all views, they need to be centered but when it's not large enough to display all views they can be laid out as they are now, simply left to right.
The interface has been set up entirely in Interface Builder. The scroll view is set to fill the entire device width - leading and trailing to superview. The first view in the scroll view has leading set to its superview so it's stuck to the far left. The last button has its trailing set to the superview - to the far right of the scroll view, to define the scrollable content area. Each view in the middle is laid out relative to the view to the left of it - leading to the previous button.
Here's a graphical representation of the current layout:
Here's a graphical representation of what I'd like to obtain:
Additional info:
The scroll view doesn't have to always fill the device width, as it is actually completely transparent. When all views are visible I want to disable scrolling. This will need to be adaptive, such that upon rotating the device it can change the layout if needed, because on iPhone in landscape all the views should be visible but in portrait they won't be.
You can try setting the contentInset property of the scroll view, which has a type of UIEdgeInsets. This property simply provides the scroll view with a certain amount of "padding", adding to the scrollable area.
You can determine how much extra space you have at the end (right-hand side) of your view, divide it by 2, and use that value to provide equal-width padding on each side.
Another purely autolayout-based approach could be:
Constrain your middle view to be horizontally centered in the superview.
Constrain each view relative to the middle view in a chain

Using AutoLayout and ensuring bounds of parent view to fit subviews when resized

I really wish I could get my head around auto layout. It seems that whenever I read an abstract description of how things are supposed to work it makes sense, but whenever I actually try and put it into practise it always causes massive headaches. So, apologies if there is already an answer out there for this but I couldn't find one.
The problem should be relatively simple. I have a container view, which contains two subviews, shown here in hideous colours for maximum readability :) :
The bottom (black) view, should remain at it's current size and maintain the spacing between it and the red view, and the spacing between itself and the bottom of yellow view.
The red view I want to be able to dynamically change its height, causing the black view to shift up/down accordingly whilst the yellow view resizes to fit both the red+black views.
For the black view, I've added constraints to:
Set the height to 94
Pin the leading and trailing space to superview
Set the top space to the red view at 51.
Set the bottom space to the yellow view at 20.
I am trying to understand what seemingly-mystical set of constraints I need to add in order that, when the red view is resized vertically, the black view stays its current distance from the red view and maintains its size, and the outer container view resizes accordingly so that it contains the red view + black view + vertical spacing between the views.
For the red view, I've added constraints to pin the top, left and right spacing to superview, but have had no luck working out the vertical constraints. Currently I've got a constraint pinning the height =114 with a priority of 999 and a constraint with height >=114 with a priority of 1000 thinking this would ensure the view is always at least 114 in height...
The fun starts when I try and manually set the height of the red view.... I've added a button on the view, and when the button is pressed, I manually set the bounds of the red view. (The red view's default height is 114):
CGRect bounds = self.redView.bounds;
bounds.size.height = 300;
self.redView.bounds = bounds;
When I run this and press the button, the view goes from this:
To this:
To me this makes no sense whatsoever. Why does this result in:
The Y origin of the red view changing? Particularly when there is a "required" constraint telling it to stay 20pts from the top of yellow view.
The spacing between the red and black views breaking down, even though the constraint on the spacing between them is "required"?
The vertical size of yellow view not changing. Again, despite the spacing between red+black, and me having tried just about every combination I can think of in terms of compression resistance and content hugging priority.....
I really want to understand this, so would be really grateful if someone can explain what additional constraints / changes to constants are required, but more importantly WHY they are required, because to me it doesn't seem clear at all how the layout system comes up with its answers....
Any clarification much appreciated.
Thanks in advance
(All code above is running on iOS 7 and built with Xcode 5.0.2).
You don't need any fancy constraints to do what you want here -- no inequalities or messing with the priorities. In addition to the constraints to the sides, the red view should have 20 to top, 51 to black view, and a height constraint of 114. The black view, has a 20 to the bottom and a height of 94. The superview (yellow) should have zero constraints to top, left and right -- no height. You should have an IBOutlet to the red view's height constraint. When you want to change its height, modify its constraint (don't set frames):
- (IBAction)resizeYellowView:(id)sender {
self.heightCon.constant = 300;
}
Everything is linked together from the top of the yellow view to the bottom with fixed values, so the only thing that can change when the height of the red view changes, is the height of the yellow view.

Resources