fill rest of view in storyboard - swift

How do i achieve the following layout within a storyboard? I have seen related answers in SO suggesting a code solution. But can it be done codeless?

For your toolbar at the top set the left, right, and top spacing constraints with a constant of 0, then set a height constraint with a constant of whatever your fixed height is.
For the bottom container view, set the left, right, and bottom spacing constraints with a constant of 0, and set a vertical spacing constraint to the toolbar, also with a constant of 0.
This will anchor the toolbar to the top and automatically fill the rest of your view controller with the container view.

Related

Center Label vertically between two UIButton's

everybody some I'm having some trouble vertically centering the or label between the Sign in with apple button and also the login button. Keep in mind that I am creating the SIWA button programmatically and setting the constraints that way also. I have tried getting the origin y coordinate for both buttons, dividing them by 2 and then setting the vertical constraint from the login button to the or label to be (loginButton.frame.origin.y - (divided by 2 value)) but that doesn't seem to work. Thanks for your help.
There's a couple ways to solve this:
Put the 2 buttons and the label in a vertical UIStackview with distribution set to equal spacing. Stackviews are very flexible too, especially in more complex layouts.
Create an empty UIView that sits between the two buttons, then add the label as a subview and center it. Alternatively, you can create 2 spacer views with equal height constraints above and below the label:
V:|[Button][space][Label][spacer2(==spacer1)][Button2]|
Very easy approach: by default, UILabel centers its text vertically in its frame.
So,
constrain the Top of the Label to the Bottom of the top button
constrain the Bottom of the Label to the Top of the bottom button
All done :)

StackView not appearing correct on all screen sizes

I have a ViewController that contains a Stack View. In this Stack View there are 3 more Stack Views. The first contains 3 labels, the second contains more Stack Views with buttons and labels, and the third contains 2 buttons and a label. And at the bottom, there is a button. The layout is fine on screen sizes from 4,7" and bigger. But when the screen size is smaller, it cuts out the top Stack View. I have tried to set constraints on leading, trailing, top and bottom in different variations (with and without top and bottom constraints) But I can't make it work properly. I have attached screenshots of the different screen types.
EDIT* Depending on the selection from the previous ViewController, the middle Stack View(the one with the check boxes) can be isHidden When its hidden, the view is correct.
Generally you don't set height on UIStackView. They are dependent on it's content. This will cause your stackview to get out of the screen height. Have you used the view hierarchy? If you want to cover the small sized phones you could put your main stackView inside a scrollView to still be able to see all content.
It's a bit difficult to diagnose what's happening without seeing the constraints you apply to the views, however I'll recommend you some things that may help:
Set the space between views using size classes so you can set the right one depending on the screen size and avoid the overlap with the below views.
In case you are doing it, don't set a height constraint for any stackView.
To align the top StackView I would use not only a top constraint to the top bar (of type greater than or equal) but also a vertical center constraint with a right multiplier (with a high priority). In this way you ensure the top stack view is aligned vertically in proportion to the screen size and with the top constraint you ensure the stackView doesn't hide below the top bar.
Make sure you are hiding the right stackView.

UIScrollView Causing "Misplaced Views" AutoLayout issues

I'm running into a strange AutoLayout related issue when I use a UIScrollView (the issue does not occur without it).
I have a UIScrollView that is constrained to the boundaries of a UIView (contained within a UIViewController), and within that, I am attempting to place a UILabel and UITextField side by side. I have constrained the UILabel to the left and upper boundaries, with it's width and height constrained (see screenshot below):
Right next to this UILabel is a UITextField, which is constrained to the left, top, and right, as well as having the height constrained. However, this results in a "Misplaced Views" warning, that states "Expected width = 163, Actual width = 413", shown in the screenshot below:
When I choose to "Reset to Suggested Constraints", the "Misplaced Views" issue disappears, but in it's place I am left with a width constraint of 413 points, which is something I'm hoping to avoid, as I would not like this UIViewController to be horizontally scrollable on smaller devices.
A scroll view has a size (the size it takes up on the screen) and a content size (the size of the entire scrollable area). In Auto Layout, the content size is automatically computed from the constraints of the items in the scroll view. This is a problem, because you are trying to make the scroll view have the same width as your screen, and then have the items constrained to that. When you do that, Auto Layout insists that you give your text field an explicit width so that it can calculate the width of your scrollable area.
To do what you want, do the following:
Add a "content view" to your scroll view. This view will be the only top level item in your scroll view. It will hold all of your content as subviews of it. Drag out a UIView and add it to your scroll view. Constrain its top, leading, bottom, and trailing edges to the scroll view. Constrain its width to the width of the scroll view. Give it a height constraint and set it however big you want your content area to be.
Add all of your labels and textfields to this content view. Now you can constrain them centered in your content view or constrained to the edges, and it will work as you want.

AutoLayout: Vertically centering two UIViews in a superview that can resize

I have two UIButtons, one on top of the other, in a superview whose height can be resized. The two buttons should have a constant vertical spacing between them, but the top and bottom spacing should resize so that the two buttons stay centered in the superview as it resizes.
I tried creating two less-than-or-equal constraints (with equal priority) on the spacing to the superview for each button, as well as a constant vertical spacing between the buttons, as shown below:
(The reason why it's less-than-or-equal here is because this view is defined at the given height in IB for 4" screens, but can be shrunk for 3.5" screens.) However, this doesn't do the trick, as you can see from the screenshot while the app is running:
It's almost as if you want to be able to tell AutoLayout that the two constraints themselves should have equal values, even if they are both set to "less-than-or-equal". Is there any way to do what I'm trying to do, or perhaps a better way?
This is so trivial to do in IB.
1) ⌃ drag from button1 to top. select "center horizontally in container".
2) ⌃ drag from button1 to left. select "center vertically in container".
3) do the same with button2.
4) now the only thing left to do is size the buttons because this is what it looks like.
This is also very trivial.
5) ⌃ drag from button1 to the left. select "leading space to container margin".
6) ⌃ drag from button1 to the right. select "trailing space to container margin".
7) do the exact same thing with button2.
The finished product, looks like this (NB I didn't quite center them, but I could have easily enough):
The simplest way to vertically center is to add a NSLayoutAttributeCenterY constraint - preferably to the element that is near the center of the view. And if all views have a vertical spacing constraints, then they will all be centred. No need to muck with the view hierarchy or add spacer views.
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:button2
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0]];
If you need to adjust the positioning, set the constant. For example: constant:-30 will move it up 30 points.
You can also anchor elements based on different logical areas of the view. For example, if you wanted to anchor your first button at 25% of the view height, you can set the multiplier to 0.5.
Agreed with rdelmar. Here's another option if you want to preserve view hierarchy.
You are currently spacing the buttons at the top and bottom using constraints. Instead, create two empty UIViews, they will be used as spacers. They should be positioned one at the top and one at the bottom of your buttons. Using autolayout constraints, make sure that the height of these two spacer views is always equal. Make sure they are pinned to the top and bottom of the buttons and the top and bottom of the superview, respectively.
In VFL: V:|-[spacer1(==spacer2)]-[button1]-(20)-[button2]-[spacer2(==spacer1)]-|.
You may have to do this in code, I'm not sure if IB can do this.
One way to accomplish this is to enclose the two buttons in another UIView, and center that view in the controller's view. Give the buttons a fixed distance to the top and bottom of this view, and either a fixed distance between them, or a fixed height for the view.

Position in relative to parent view with auto layout in Objective C

I have a UITextView that I want always to be 10px from the bottom of it's parent view (the scrollview). Problem is that I don't know how to tell the auto layout that it is supposed to do Bottom Space To: Parentview, instead of superview.
This is what I have now:
Update:
I need something similar to this:
I got that from here - http://www.techotopia.com/index.php/Working_with_iOS_6_Auto_Layout_Constraints_in_Interface_Builder - I want to have a UITextView in relation to the view it is in.
Click the gear for the “Bottom space to: superview” constraint and edit it. Set the constant to 10.
UPDATE
I've investigated this a bit and decided there's a bug in autolayout. Specifically, autolayout acts as if the size of the scroll view is 0⨉0 instead of its actual size.
Because of tis, if your text view has top-space-to-superview constraint and a bottom-space-to-superview constraint, only the top constraint will be honored. (I tried setting the priority of the top constraint to 1, the minimum, and the bottom constraint was still ignored.) If you delete the top constraint in viewDidLoad, the bottom constraint will be honored, but the text view will be laid out as if the scroll view's height is zero. This means that the text view's bottom edge will be 10 points above the top edge of the scroll view.
This happens in my testing with both a storyboard and a xib.