Dynamically sized stackView for less content - ios

I have custom XIB's which I will be using to create my ViewController at runtime. Which all XIB's are to be included inside the ViewController will be decided at runtime.
I am using a stackView for that purpose which I have added to the storyboard and constrained it to leading-triling-top-bottom of the superView. That means the stackView will be stretched to the height of the viewController.
Now when i have few Custom Views(or XIB), say 3, it should not cover the complete screen but rather stick to it's size and be added to the stackView
But my problem arises here: Since I have constrained the stackView to complete screen(as sometimes the number of XIB can be a lot more and will surpass the size of the screen and hence I might need a scrollable stackView), it shows like this
I have found kind of a hack here but I don't think that's gonna cut
StackView's Alignment - Fill, Distribution - Equal Spacing (0)

step 1. make the bottom constraint between super view and your stack view as Equal or more
step 2.
make the height constraint to your stack view with priority 1 and constant 0
step 3.
ensure you views inside stack view layouts correctly - all edges should be installed in each views

I solved it by :
Removing the bottom constraint of the stackView
Changing the Intrinsic size under Size Inspector from System Defined to Placeholder and setting the height to 1

Related

Adjust height of xib containing UIStackView when elements are hidden

I have an xib containing a stackview with child stack views (following Ray Wenderlichs tutorial). I wish to hide one of the child stackviews so that the height of the xib adjusts to the visible child stackviews. However currently it remains at the original fixed height and the visible stackviews are spread across it.
Here are the settings for the top level stack view:
Can anyone advise on how to make the xib height adjust to fit the visible content size?
Edit 1:
After removing the heights of each of the child stack views and make the bottom constraint of the top level stack view >= 8 to the superview, the problem still happens but the layout has changed:
Edit 2:
After add a trailing constraint, the child stackviews no longer stretch across the xib, but the height of the xib does not compress:
Issue:
The issue is because you've fixed the bottom constraint of the StackView to the HeaderView's bottom as 8.
Now, the StackView won't be able to reduce its height according to its content.
Solution:
Make it as >= 8, i.e.
bottom >= StackView.bottom + 8
That way StackView will adjust its height as per its contents.
Edit:

UIStackViews inside UIStackView giving errors

I want to place 2 Horizontal UIStackViews inside another Vertical UIStackView. The main stack view is in the contentView of a UITableViewCell. Each of the nested stack views has 2 UIViews. The alignment is set to 'Fill' and distribution is 'Fill Equally'. For the main stack view both of them are set to 'Fill'. All of the UIViews has 2 elements, which are connected with constraints. When I place them in the storyboard I'm getting errors 'Need constraints for: Y position, height'. What am I doing here wrong?
EDIT: Also I'm hiding the UIViews depending if they have data from server or no. If both UIViews dont have data, then I hide the whole stackView.
You are missing vertical constraints for some of your views. Just because the stack view is set to "fill" does not mean the autoconstraints engine will know how tall to make each view. See if you can match the same constraints portrayed in the following screenshot and let me know if that solves your issue; these constraints make the views have equal height.
Need constraints for: Y position, height
this means that you place a view ( subviews of the inner stacks ) with no intrinsic content size so make sure to give it a height ( unlike label and button which already have ) and hook properly from top to bottom with their superviews

Basic Auto Layout - nested width and dynamic height

Simple goal, but it demonstrates situations where Auto Layout gives me a headache. I want to have a stack view with a width of 256pt and a dynamic height based on layout (I shouldn't have to manually specify the height).
Inside it should be an image view sized 64pt x 64pt, which should also be centered horizontally as well as constrained 8pt from the superview's top. Note that the image view isn't the only child, hence why the stack view's height must be sized dynamically.
Auto Layout now tells me there's a conflict between the 256pt width constraint of the stack view and the 64pt width constraint of the image, as well as some mysterious "leading = Image.leading" and "trailing = Image.trailing" conflict which I can't even delete nor find.
Am I missing out something here regarding Auto Layout? I expect all logic to be contained in the interface builder, so no code should be required.
Running Xcode 9.1
Layout image
There is nothing to confuse. iOS clearly telling you the issue.
StackViews take size based on the size of child components (this is called implicit size) unless its been overriden manually as in your case which is 256pt.
Because stackView is just a container for multiple childViews stacked either horizontally or vertically, now because you have added only one imageView to it, it adds the leading and trailing constraint to it which makes absolute sense because you added a single view to the stack of view's , now what should stackView do? stretch childView (in your case imageView) to its own size.
But then you did not allow it because you added width constraint to imageView now when it tries to increase the imageView's width imageView's constraint wont allow it.
Hence it is complaining that there are too many conflicting constraints. Thats all :)
some mysterious "leading = Image.leading" and "trailing =
Image.trailing" conflict which I can't even delete nor find.
You cant delete them because, imageView is the only view inside stackView. Because there is only one child view to stack, stackView will start from left side (leading) to right side (trailing). Because now stackView has its own width it tries to change the width of imageView to reflect the same! But images width constraint prevents it from happening.
What are you trying to achieve with imageView added to stackView. If there is only one view in stackView, adding stackView does not make any sense. Reconsider what you are doing.
Finally, when you have only one childView in stack view, adding horizontal center does not make any sense (no matter vertical/horizontal stackView).

Position and size are ambiguous for “view”

I have set pin to all view but i got continuously this alert !
I have seen that this is because of height and width constraints but i didn't add height and width still i got this error !
This alert should be avoidable or not.
A UIView has no intrinsic size meaning none of your views know how large they should be and thus cannot be laid out the way you have them. You can set the height of each one to a fixed number but if you want them to scale I recommend using Equal Heights and Equal Widths and set the multiplier to the proportion of the view you want the little views to size to be. You could do this so many ways.
I am going walk you through one way that I think is the quickest(using StackViews) for my own sanity but the same logic could work with more dragging from each view.
Step 1:
Drag a Vertical StackView to the top of the storyboard. Add the following constraints. pin leading, trailing, and top =20. Then drag from the vertical stack view to the main view and choose equal heights and change the multiplier to 0.6(60% of the main view height). See image
Step 2:
Add a single horizontal stackview as an arranged Subview to our vertical stack view. Now add 3 UIViews and change the colors to desired colors. Change stack view to Alignment-Fill and Distribution-Fill Proportionately. Also add spacing=20. See Image
Step 3:
Choose your horizontal stackview that you just created in step 2 and hit Command-C to copy it. Hit Command-V to paste it. Note- If it does not paste it into the vertical stackview drag it in to the vertical stack view. Not there yet but close. See image
Step 4: Go to the vertical stack view and change it to Alignment-Fill and Distribution-(Fill Equally). Add Spacing of 20. You should now be a point that looks like this. See image
Step 5. Add a horizontal stack view below the vertical stack view and the bottom layout guide. Pin to all four sides at 20. Add three views and change the color to desired color. Change Alignment-Fill, Distribution-Fill Equally, and spacing=20.
Step 6. Adjust verticalStackView equal heights multiplier to maybe a lower number(0.5) to make it look like your view.
Step 7. Reap the rewards
The Big takeaway is that a UIView needs to know how big it is. UIStackView in this case tells the views how big they are. You could just have easily set the height and width of one of your views in your screenshot above to a percentage of the view. Then drag from that view to all of the like sized views and set equal heights/widths. That would have been more tedious and you can see why I used Stackviews for the example. Good luck.

Simple scroll view constraints change?

I created a scroll view in Xcode that works awesome because of this video.
https://www.youtube.com/watch?v=3PIm8-lKAYw
When I was messing around after I made it I found out that if I clicked on the scroll view and went to Show the Size Inspector or the fifth button on the right hand side of the screen I had the option to make a constraint called Top Space change in value that caused the scroll view to become bigger and smaller. I decided to see if I could find a way to change the constraint programmatically by simply using dot notation and the equaling it to an int value that I wanted.
So what I'm trying to figure out is there a simple way to change these constraints values programmatically that change the scroll view constraints values?
Without actually following that tutorial (and there being no code in your question) I'm going to make a few assumptions.
Yes, it is possible to change the scroll view's content size by manipulating constraints in your code. If you are creating the constraints in a xib or storyboard, you will need to make sure they are hooked up to IBOutlets so that you can access them in your code.
If you have 2 views arranged vertically that affect the vertical content size of your scroll view, increasing the space between these views would also increase the vertical size of your scrollview's content size. The following would increase the space between 2 views by 20 (assuming a multiplier of 1) and subsequently increase the scrollview's vertical space by the same amount.
// This is a vertical space constraint created in your xib or storyboard between 2 views that drive the content size of your scrollview
someVerticalSpaceConstraint.constant += 20;

Resources