Im very new to xcode so bear with me. I added a vertical Stackview and want to add a bunch of textviews and buttons starting from the top. I managed to use constrains to stretch the Stackview to the screen on all sides.
Now when I add 3 textviews this happens, and its all wrong: first the textviews stick to the bottom for some reason, second one stretches out the remaining space which is obviously wrong. What can I do to make it correct, i.e. all textviews should be at top right under each other with correct width and height (width fills the screen, height is whatever the default height is)
A UIStackView will arrange its subviews.
If you set a Height - either explicitly or by constraints on the Top and Bottom, the stack view will arrange the subviews to fit into that height - when set to Fill or Fill Equally, it will "spread out and resize" the subviews.
If you don't constrain its Height, it will still arrange its subviews, but it will expand its own height based on the heights of the subviews.
So, for your case of 3 text fields, constraining all 4 sides results in the subviews being arranged to fit the height of the stack view.
If you constrain the stack view only to Top, Left and Right, you get this (main view is blue, stack view has spacing set to 8):
Related
I have a UIStackView in which I programmatically add buttons based on the available actions for some content. I'd like the stackview to grow horizontally as each button is added and each button to be only the width needed to contain the text.
Where I'm at now, all buttons are sized to their text in the stackview and the first button takes the remainder of the stackview width as layed out.
What I'd like to do is have the stackview size in width dynamically based on the buttons added and how wide each button is.
This is what I have now:
Horizontal stackview with three buttons
Give your stack view these properties:
Constrain the Top of the stack view, and constrain it Centered Horizontally:
As you add buttons, its width will expand to fit the buttons, and it will remain horizontally centered:
Edit
And, if you want the stack view to expand left-to-right, constrain the stack view's Leading instead of centered:
I'm trying to set an empty vertical UIStackView inside a UIScrollView so that I can fill the UIStackView dynamically on runtime
I tried the solution given by apple here but when I do that, the Auto Layout tool tells me that there is a missing constraint which is either the Y position or the height of the UIStackView.
The only difference I have between my UIScrollView and the one from the example is that I don't add a button inside the UIStackView.
When I fill the UIStackView on runtime, the logs say it has to break some constraints and then the UIScrollView fills the screen all the way to the bottom, pushing other views I had there out of sight.
Is this the right way to accomplish what I want? Or is there any other solution?
EDIT:
This is what I have, the logo constraint is only aspect ratio relative to itself
Set up your constraints as you have them, but without the empty stack view in the scroll view.
Next:
add a UIStackView to the scroll view
constrain all 4 sides of the stack view to the scroll view
constrain the stack view width equal to the scroll view width
constrain the stack view height equal to the scroll view height
IB should show all constraints satisfied.
Then - and here's the key - edit the stack view's Height constraint and set it to be a Placeholder:
This Height constraint will now be removed at Build-Time. Any elements you add via code as arrangedSubviews will determine the height of the stack view, which will, in turn, define the vertical scrollable area (the .contentSize) --- all handled by auto-layout.
I have a view hierarchy that looks like this (based on other answers and Apple's advanced AutoLayout guide for working with UIScrollView):
The 2 steps required for ScrollView are:
Set up constraints for position and size (frame) of ScrollView: The same way you do it with any other view.
Set up constraints for content size: By making sure that there are constraints from the ScrollView's subviews touching all edges (leading, trailing, top, bottom) of the ScrollView, if you're doing this in interface builder and not programmatically.
Step 1 worked fine at first and this was the result:
No problems with position and size as expected. I just need to define the content size (content height and content width) now in Interface Builder with Step 2.
Now I add the constraints touching all 4 edges of the ScrollView like so:
Suddenly, the ScrollView doesn't know it's position and size (frame) anymore.
I've looked at other answers and followed the various steps, but can't seem to resolve this issue. Sorry I'm not able to post Storyboard screenshots because of privacy issues
Set the scroll view's top, bottom, leading, trailing constraints to its superview to 0.
Set the view that is inside the scroll view and set its top, bottom, leading, trailing constraints to its superview to 0.
Select the view that is inside the scroll view, go to the size inspector and set the "Intrinsic size" to "Placeholder".
Scroll views can be a little tricky at first. You really have 3 parts:
Actual frame of the scroll view
Actual frame of the subview(s) contained in the scroll view
The contentSize of the scroll view - that is, how far it should scroll in either direction
So, 1. is pretty straight-forward.
The second part also seems straight-forward, except that we tend to "pin" subviews to the inside edges of their superviews. In the case of scroll view subviews, those constraints are what defines the contentSize. You also have to make sure the subviews have a "size".
Starting with just one subview, you would:
set the scroll view's constraints as "normal".
set the size of the subview - just for demo purposes, set it to 100 x 100
pin all four edges of the subview to the four edges of the scroll view
Run the app. Assuming you set background colors so you know what you're looking at, you should see the scroll view positioned and sized as you'd expect... you should see the subview of 100 x 100 sitting somewhere inside the scroll view... and you will likely not be able to do any actual scrolling.
If you go back and change the subview to, say, 100 x 800, and still have its bottom constraint pinned to the bottom of the scroll view (the subview's superview), and run the app again... You should be able to scroll up and down for the full 800 pt height of the subview.
The way to think about it is: the scroll view's content - whether it's one or many subviews - has to define its own size, which will define the scrollable area (the scroll view's contentSize).
Hope that makes sense!
My problem is slightly different from other's 'Swift UIScrollView' problems when using auto layout:
Problem:
Unlike others, when I run my app, it scrolls. My problem is that the scroll cuts off the bottom 20-30% of the content. I can pull to see the buttons did build and are down there, but when I let it go the scroll snaps back to a false bottom which cuts off my content!!! I've been trying, for days, to fix it to scroll the entire height but it continues to cut off!!
Description of app:
I used auto layout to layout 6 buttons and labels. Each button a rectangular image, with a label directly beneath it. (sorry, the site won't let me post pictures!)
I have my views arranged like this:
MainView > ScrollView > ContentView > Buttons & Labels
I have my contentView pinned to my ScrollView and my ScrollView pinned to my MainView. My buttons and labels all have constraints that are building correctly, to create a list that looks like:
Rectangular button
Label beneath it
Spacing
Rectangular button
Label beneath it
Spacing
Etc.
Can anyone tell me why I can't scroll the full length of the view?
Your description of how your items are constrained is vague, so I'm going to list all of the constraints you need to make this work. Then you can compare what you have to what you need and adjust accordingly.
Your ScrollView should be pinned on all 4 sides to the MainView. (This isn't absolutely necessary. You can constrain your ScrollView however you want, but make sure it can grow as the device and/or orientation changes).
Your ContentView should be pinned on all 4 sides to the ScrollView with offsets of 0.
Since you want your ScrollView to scroll vertically only, constrain the width of the ContentView to the width of the ScrollView using an Equal Widths constraint. To do this, in the Document Outline view, Control-drag from your ContentView to your ScrollView and select Equal Widths from the pop up.
The height of ContentView will be set by the sum total height of everything in it. In order for this to work, your topmost button needs to be pinned to the top of the ContentView, all of your buttons and labels should be pinned to their nearest neighbors, and the bottommost label should be pinned to the bottom of the ContentView. In addition, all of your buttons and labels should have constraints for their widths and heights. I would suggest setting an explicit width constraint and explicit height constraint for your buttons and centering them horizontally in the ContentView. For your labels, set an explicit height constraint and pin the left and right edges to the ContentView.
If you have these constraints and no other ones, your ContentView will be properly sized.
Using contentView, like you said, usually fixes the issue. So chances are you need to take a second look at your contraints. Maybe try this solution in a clean/new project to see that it works. (it does work). My guess would be that some of your constraints conflict each other.
Otherwise I think it would be a good idea to setContentSize of your scrollView in your viewDidLoad.
Another hack would be to place 2 UI objects with their alphas set to zero on the right top corner and left bottom corner. This would hint scrollView to set its contentSize.
In IB I have a view controller that contain a scrollview.
The red view is inside the scrollview
The minimum height of the red view is 504px, so on iphone 4 it should scroll and on iphone >=5 it should extend and layout the buttons to fill the blank.
I set the constraints of the red view to 0 from top, leading, trailing and bottom of the scrollview and also centered horizontally and vertically.
My redview has a minimum height of 504
The blue and green views have equal height
Everything is fine for iphone >=5 but for iphone 4 the red view is compressed to be the size of the scroll view and the buttons are touching each others.
After multiple constraints adjustments I'm wondering if it's even possible to do what I want 100% in IB with autolayout
You say (emphasis mine:)
"I set the constraints of the red view to 0 from top, leading, trailing and bottom of the scrollview and also centered horizontally and vertically. My redview has a minimum height of 504"
First, I can see some redundancy (the bold part).Your redView does not need the vertical constraint since you have already pinned it on the edges of the scrollview and has a defined minimum height.
But this could or not be the cause of the buttons coming closer together, depending on the rest of the constraints.
Have you set vertical space constraints for the buttons?