I'm currently setting up a login screen that should ultimately look something like this:
I've successfully accomplished all the constraints needed to create the desired look on all screen sizes, however, I can not seem to figure out the constraint needed to correctly align the "Don't have an account? Signup". I've designed it so the "Don't have an account?" is a UILabel, and "Signup" is a UIButton. I've just aligned these side by side.
The UILabel, "Don't have an account?", has the following constraints:
The UIButton, "Signup, has the following constraints:
These constraints seem to accomplish what they need to on screen sizes 4" and below. however the 4.7 inch, and 5.5 inch (iPads excluded), have wide spacing between the UILabel and UIButton. I've read Ray Wenderlich's tutorial on auto layout, and still can not figure out the problem (I'm new to auto layout, but I have an idea what I'm doing. I'm not just adding random constraints hoping it works).
This is what it looks like on all my targeted devices:
Notice as screen size increases, so does the gap in between the label and button. Any help is appreciated.
You are setting the leading space of the label to its superview, and you are setting the trailing space of the button to its superview. So obviously if the superview gets wider, they are going to get further apart.
So if that's not what you want, don't do that.
The actual solution to what you want to do is quite tricky. You want these two objects to behave as a group, and you want that group to be centered. There's no simple way to express that. You will need to make a group. In other words, you will need a container view, give that view an absolute width and center it, and put these two objects inside the container.
New in iOS 9, a UIStackView can help you with this.
Another approach that works is to use a couple UIViews as spacers. I sometimes prefer this to containment, but it is probably a matter of taste.
Remove the leading constraint from your UILabel.
Remove the trailing constraint from your UIButton.
Add a UIView with clear background in front of your UILabel. Set a leading constraint from this UIView to the container leading edge with constant 0. Set a trailing constraint to the UILabel with constant 0.
Similarly, add another UIView after your UIButton. Set a leading constraint from this UIView to the UIButton with constant 0. Set a trailing constraint from this UIView to the container trailing edge with constant 0.
Both UIViews will need a Y position and height. These are somewhat arbitrary so I would set Align Center-Y constraints with your UILabel, and height constraints of say 5.
Here's where the magic happens: select both UIViews and set an Equal Widths constraint. This forces the UIViews to occupy equal space on both sides.
UIStackView is overkill for this situation. Just
Put the label and button in a single UIView.
Constrain the label's left and center Y to the container view.
Constrain the button's right and center Y to the container view.
Constrain the label's right edge to the button's left edge.
Set the horizontal content hugging priority of the containing view to 1000.
Constrain the containing view's center X to its superview.
You can do it to your existing code only by setting few constraints. And this would work on all resolutions even on the iPad. You don't need to group them , i have attached the images to show the constraints that i have applied.
And for the button set this constraints
It would be shown properly on all the devices kindly have look as to how it looks on all the resolutions and also in the landscape mode of each resolution
Thanks
Omkar
Related
I have a cell in which I place four buttons and four labels. Each button gets assigned a picture with width 50 and height 50. Furthermore, all buttons have a corresponding label describing what they're intended for.
My objective is to have the buttons and labels resize to keep the buttons' and labels' aspect ration intact while the screen dimension changes on different devices. I have been playing with auto layout changing the hugging and compression to achieve this but haven't been successful yet. Any help would be much appreciated...
I think you should take a look at a UIStackView, because this seems exactly as a use case for stack. Just put each pair button/label in a stack, and then all four pairs into a horizontal stack, which you constraint to the cell itself. You should be able to handle all you need just by configuring the stack’s properties (axis, distribution, alignment, spacing).
Embed your button and label into a view. Set the width of this view equal widths to content view and change the multiplier value to 1:4. This will adjust the widths of the views according to superview. Also, set the top and bottom constraint to 0 for this view.
Provide center align y-axis constraint to button after setting the width and height constraint to 50. Set its top constraint to a value you deem fit.
Set labels's leading and trailing constraint to a value like 8. Choose center alignment for text. Also, provide top constraint to buttona nd bottom to its superview.
Copy the view and paste to create the three views and provide them equal widths constraint to the first view. Also, provide their leading, trailing, top and bottom constraints.
Here are a fast tutorial in how to achieve that:
1-
2- completion of the first Gif:
Note you can achieve the same output using a UIStackView
I am making a note taking app in xcode8 for iOS 10.2. The note is consist of a textfield, textview and imageview. I am adding textview and imageview in separate scrollviews (to provide the facility of zooming and adjusting image). Then I have added both scroll views in a stackview to ensure that imageview and textview stands side by side in a landscape mode. To do that, I have added variation to axis property of stackview( width=any, height= compact and Gamut=any, and set that to the horizontal, as shown in right corner of screenshot to see view hierarchy without any constraints).
I have tried many constraints but, every time it fails to adopt. Let's take an example, I am adjusting size of the scrollviews on the size of content(by setting top,bottom,leading and trailing constraint), the stack view is adjusted to the main view. Now, the only thing that needs to be adjusted is text view and imageview with respect of stack view. But, here is the tricky part If I include a fixed trailing constraint of text view to the stack view; it will work in portrait mode.As soon I turn into landscape mode that constraint will not work(the trailing constraint which have 0 distance from stackview) because the edge will be side to the imageview not to the stackview(because I am putting image and text side by side as explained above) which will make textview larger than required, same goes for imageview's leading constraint to the stack view and vertical distance constraint betweem image view and textview.I think the root of the problem is I have made a variation to the axis of a stack view (in order to get text and image side by side in landscape mode) but, that was necessary part.Can anyone have solution for this? Do you think there can be other problem? Should I choose Intrinsic Size of scrollviews to placeholder option or let it be system default?
Thank you.
So I hope I understand the question and I will try to walk you through what I understand you hope to accomplish. I preface this by saying I just started using UIStackView because of backwards compatibility.
Note. To get the magic of ScrollView with AutoLayout I almost always embed them in another UIView. There are reasons to not but in this case you will see how valuable this is to AutoLayout.
Step 1) Drag your UIStackView and add Top,Bottom,Leading, and Trailing. Now add 2 UIViews and set the UIStackView to Fill Equally. It will now look like the image(Background colors to check your work).
Step 2) Now add a UIScrollView to each of these UIViews. Add Leading,Trailing,Top,and Bottom on each of these.
Step 3) Add a UITextView and UIImageView to the ScrollViews respectively. Now Autolayout is mad at us :( but we will fix that.
Step 4) Drag from the UIImageView to the View that is holding the UIScrollView(First Set of Views we added). See image
-Choose the option to add Equal Widths. See Image
Repeat the same step but add Equal Heights. Now add Top, Bottom, Leading, and Trailing to the ScrollView.
Step 5) Repeat exact Step 4 with UITextView
Your final view hierarchy should look like this.
Now you can rotate your UIStackView and do what you want I think.
And Horizontal
Side by Side Preview
I did add a <= 0.1 equal heights multiplier on the textfield at the top but I don't know if that was necessary.
Enjoy.
Everything looks fine in IB. When I run my app using an iPhone5/iPhone6/iPad sims, it's completely mangled.
In IB:
In iPhone6 sim:
In the above sim, the buttons are cut. The textfield and textview are also cut. For the TF & TV, they are aligned center but trail off the edges on both sides.
I have the buttons width set
Editor > Pin > Widths Equally
The title label is set with a
Horizontal Center in Container
constraint
The textfield and textview also have
Horizontal Center in Container
and
Editor > Pin > Width
Is there some way to fix this?
-- EDIT --
After a few tries with constraints, looks like I have everything working except the two buttons.
Current listing of constraints:
As suggested by others, you should consider using the Auto-layout feature if you plan on constructing your views using the IB.
Here are some tutorial links:
RayWenderlich.com Part One
Youtube video This one covers a bit of size clases
Hope they help.
UPDATED:
I've read your updated post, you need to add width and height constraints. The view you see in the IB right now is 600 by 600 points, and the simulator one is smaller, which means that if you leave it as is, when you run the app you'll only see what the iphone screen has the capacity to show.
You need to add more constraints than what you used, try defining an equal width for the buttons, and assign the left one a left margin constraint, the right one a right margin constraint, give both of them vertical spacing constraint related to the text view or long label, the text view or long label should have left and right margin constraints, a height constraint and a top constraint to the textfield, the textfield should have a vertical spacing constraint to the label, also left and right and height constraint, and last the label should have leff, right and height constraints plus a top constraint to the main view.
I feel that those are all you need, but Xcode will through warnings at you if it feels you are missing something.
Try it, and let us know.
Suppose that I have the following view controller and this is how I want to see it on all iPhone:
If I run it on iPhone 6 it has the following look:
Here you can notice that UITableView not fit the whole screen and UIImageView doesn't placed at the bottom of the screen.
How can I achieve the required behavior via constraints in XCode 6? I thought that I need the following constraints:
Leading space and top space to container margin for UITableView
Bottom space and trailing space to container margin for UIImageView
Vertical Spacing between UITableView and UIImageView
But it doesn't work as expected even after auto-resolve constraints issues:
Thanks in advance.
Ok, a few things here:
Each view needs enough constraints to define it's x and y position, and it's width and height unambiguously. To start with, go back to Interface builder and delete all of your constraints and lay out the view as you would like it to look. You want to have control over every constraint added, don't let IB automatically resolve the issues, as in all likely hood it won't do what you want.
Do you have an image that is the size you want it to be on screen, once you've factored in #2x, #3x etc? If so, then your job will be easier, as the width and height of the image view can be defined by the width and height of the image (ie the image view's intrinsic content size).
In order to use Autolayout effectively, you need to think about your view holistically, and think about how you want your views to behave when the screen size changes, be clear in your head about the behaviour.
To achieve the layout you want, I would do the following:
Constrain the tableview's leading, top and trailing edges to the superview, with a constant value of 0. This means it can get wider and thinner with the device, it will stretch horizontally, but always stick to the top. This has defined the tableview's x and y position, as well as it's width (height still to go, but keep reading...)
Constrain the image view to match the horizontal centre of it's superview (x position defined) and constrain it's bottom edge to the superviews bottom edge (y position defined). If've you've got the right sized asset, then that will take care of the width and height too. If not, you could go ahead give it explicit width and height constraints.
Now we can constrain the tableview's bottom edge to the top of the image view, with a constant of 0 (ie touching). Note we haven't give the table view an explicit height constraint, so as the device screen grows vertically, the table view will stretch vertically.
Autolayout is hard at first. I'd recommended lots of reading to get over the initial hump, really get to know what a constraint is doing, it's limitations, and the way in which the system parses constraints to translate them into frames. This book is really good, and really helped me learn:
http://www.amazon.co.uk/Auto-Layout-Demystified-Mobile-Programming/dp/0321967194
Best of luck
First make sure you have selected the correct size class. The 'Compact Width | Regular Height' size class must be selected in the Interface Builder. Now add the Trailing space,Leading Space, Top space and Bottom space constraints to the table view. For the image view set the view mode to Aspect fit and add the constraints : Align Center Y ,Top space,Bottom space, Leading space, Trailing space and Aspect Ratio .
I'm trying to keep my UILabel centered horizontally. I have tried in IB setting leading and trailing, but that simply stretches out the entire label, and I need it to stay the same size. Everything is set up using Editor and the Pin function in IB and not coding. Suggestions?
If you want to keep all the time buttons together and aligned to the center. Put them all in their own view, arrange how you wish. Then fix the length and width of the view and center it in the container like Aaron suggested. I do believe you will need to make one more constraint. Perhaps pin the view to the top. Hope this helps.
Seems too obvious, but did you try nsconstraint of width = XXX. Label should say same width and the leading trailing should keep it put.
For keeping a UILabel horizontally centre, add the following constraints:-
Width constraint to the label.
Height constraint to the label.
Top/Bottom Constraint for placing the label vertically.
Horizontal centre in container.