How To Add Storyboard Constraints For Equal Spaced Buttons - ios

I am trying to add two buttons to a view that also contains a table view. I want the two buttons to fill the width of the screen for different screen sizes (portrait only). There is a minimum width of say 100 units for the buttons to hold the text, but I would like them to be wider for larger screens. I would like the space between buttons to be at least 20 units and at least 20 units of space between the outside edges. This seems like it should be straight forward, but I can't make sense of the align and pin constraints in the Storyboard auto layout. So far, the tutorials I have seen are confusing and don't seem to cover the right amount of detail to help me. Please provide me with some guidance. Below is the layout before constraints are put in place.
And here is what the layout would look on a 4" iPhone:
I have already spent a day trying different combinations of constraints, but continue to have problems. Just when I think I have something that works, it won't build because it says I have conflicts.
I am trying to use the following tools (along with the align tools - not shown) to create the proper constraints. I have tried selecting one or both buttons and then using the editor to set the constraints, but each attempt looks bad. Even when I choose "Reset to Suggested Constraints", I get wacko results. Please help with suggestions on how to accomplish this seemingly basic task.

You must have:
Leading for first button 20
Trailing for second button 20
horizontal spacing between buttons 20
equal widths for both buttons
width >= 150 for each button

Related

Constraints with static cell are ambiguous

I'm having some problems with properly setting up my static cell the way I want it while making it look good for different screen sizes.
Somehow I don't seem to get how constraints are supposed to work.
One of my views contains a UIViewController with a table view. However, if I change my preview device in the storyboard to, say, an iPad, the table view doesn't get resized. Am I supposed to handle stuff like this from code only or is there a way to handle this from the storyboard (like setting width and height to always fill)?
I'm trying to set up a static cell so it looks good on devices with different screen sizes. Things work well enough when I have only two elements (e.g. one label left and one label right - just like in the standard template), but as soon as I add more things, I'm running into a lot of warnings, e.g. that width and height are ambiguous.
To me, it seems like I'm missing some key concept of constraints.
Look at the picture provided. What I want is the following:
Date to be a certain distance away from my left table border
The Stack View of volume + pic in centered in the middle
pic & price & label (there is one more for the measurement) to be represent the right label
I'm unable to actually try this at the moment but here's the path I would go.
Date:
Fixed Top, Bottom, & Leading to Container constraints to 8 (or whatever you'd like).
Volume Stack
Fixed Top & Bottom to Container constraints to 8.
Price Stack
Fixed Top, Bottom, & Trailing to Container constraints to 8.
You'll have some overlap issues with smaller screens at this point. You should get the "Red Circle" to suggest which constraints to add. Click and read each one and it will be specific enough to walk you through which you want resizing, resetting priority, etc.
*I hate dealing with constraints.
Good luck! I'll try tonight to see if I gave an acceptable answer. :)

Can't get Auto Layout and Stack Views to Auto-Adjust Properly (Swift 3, Xcode 8)

I'm new to iOS development so naturally I'm having some issues with my stack views and auto layout constraints in Xcode. Originally I had used just constraints and the pin menu to align everything but I'm really trying to get stack views down so I went back and implemented them.
If you look at my images above you'll see that in my app I created a couple of stack views:
Status Bar vertical stack
Section 1 vertical stack
1st divider (which is just a view with a height of 0.5 and is not inside of a stack)
Section 2 which contains 2 horizontal stacks inside of the main vertical stack view
2nd divider (exact same thing as 1st divider just between Sections 2 & 3)
Section 3 contains a vertical stack and horizontal stack inside of the main vertical stack
And all of these stacks plus the 2 dividers are grouped together in 1 super vertical stack called User Interface.
One of my problems is that I can't set top and bottom constraints between my stacks and dividers. As it stands, there is too much space for my liking between the sections and dividers. If you look at image 1 I tried to set a top constraint of 15 between Section 1 and Status bar. I also tried to set a top constraint of 15 between my 1st divider and Section 1, and so on and so forth. I'm getting conflicting constraints and I just can't figure out why. All they say is Section1.top = Status Bar.bottom + 15 , 1st Divider.top = Section1.bottom + 15, etc.
Any ideas on how to resolve the conflicts? Every time I try to move a divider it snaps back in its original place and adjusting the constraint numbers give me the same errors.
My second issue is that I can't get User Interface to fit inside of it's super view. I want my app to fit in all iPhone screen sizes and to auto adjust accordingly. What I tried doing is using the pin menu and pinning each side of my User Interface stack with a constraint of 0 (Constrain to margins unchecked). User Interface is aligned and without any conflicts but then all of my stacks get squished as seen in image 2. This results in a couple of errors saying that some of the heights and vertical positions of my labels are ambiguous:
Height and vertical position are ambiguous for "Bill Amount Text Field".
Height is ambiguous for "BILL AMOUNT".
Height and vertical position are ambiguous for "Tip Percent Segment Control".
As you go down the screen sizes there are more errors as more labels are being squished. And I already set individual top and bottom constraints for each label. Even when I implement a set height for each label, the error messages go away but not all of my labels appear within their stack. I tried messing around with the Alignment and Distribution menus and selecting different ones for my stacks but none of them seem to fix the issue.
Any help would be greatly appreciated or if I'm going about this all wrong please let me know. I'm using Xcode 8 beta 4 and wrote the app in Swift 3.0.
Refer to this documentation - there are pretty clear explanation of all auto-layout concepts.
I presume that your problem is that you use one big stack view, where each element fills proportionally to others. Try to fix this out.
One little advice, stacks are really good thing, but you should not abuse it :)
TL;DR;
From my experience. Stop using Interface Builder and create all views in code. With new anchor system or frameworks like SnapKit it's very easy. The benefits you get:
Faster development (after some time of practicing)
No stupid warnings from Interface Builder
Easier to merge when you work in a team
XCode almost never crashes
I was fighting with IB for few months and now I'm totally happy.
Good luck.

Autolayout problems in bigger devices

I am developing an iPhone app in which, i have made this page using autolayout
but it shows unwanted spaces above Register Me(yellow button) in bigger iPhones
Constraints given are:
top,bottom, leading and trailing with respect to its subviews to all the controls. (there is no warning or misplaced constraints i see in xcode)
Here is the screenshot of iPhone 4s
Here is the screenshot of iPhone 6+
I want to minimize the empty spacing in bigger iPhones...
How do i solve this problem?
Please help and thanks in advance
Heres a suggestion for you. You have roughly seven regions of interest there. First one is the title 'Register Kano .. ' etc. Then there are 5 text entry areas - name, email, password, etc. Finally you have 3 small lines of info text - I would count this as one final area, so 7 in all.
What I would do is create 7 parent UIViews to put that stuff in. I would give them 'equal height' constraints, and make them sit above and below each other with no gap. Then as the iphone screen changes height, those areas stretch out height-wise to fill the area. Heres a rough mockup :
Select all those UIViews and select the 'equal heights' constraint :
Then every view except the bottom one needs these constraints (top, leading trailing to superview 0px)
Then your bottom view needs those plus 'bottom' too :
So all that remains to do is to put your content in each of those boxes, but centre them in terms of vertical position relative to their superview.
If your intent to target iOS 9 users, you should use UIStackView, the provide a lot of flexibility in terms of alignment and distribution.
If not, then you or your design team has to find a solution.
You can update the margin contraints of your controls on big devices.
This would add space between each rows on big screens, will looks better as you ask.
Something like :
myControl.heightConstraint.constant += 20.0f
This is how I would do, but you have to decide how you update your layout for big devices
#Krunal you can use the size class and set the constraints accordingly so it will give a brief idea how to fit the UI design for every device!!
you can set constraints relative to height of your base view. This will make your interface objects evenly distributed over layout. Lets assume you have 8 regions. for registerLabel
registerLabel.leading = baseView.leading
registerLabel.trailing = baseView.trailing
registerLabel.top = baseView.top
registerLabel.bottom = baseView.bottom * (1/8)// it will be always proportional to height of view
then for icons at the beginning firstIcon
firstIcon.leading = baseView.leading + 10
firstIcon.height = firstIcon.width
firstIcon.height = baseView.height*(1/9)// to give a gap between icons
firstIcon.bottom = baseView.bottom * (2/8)
and then you can set textfield's constraints according to firstIcon
for other icons you can go on with 3/8, 4/8, 5/8, 6/8 and set the relative textfields constraints according to that icon.
and lastly for registerMe button
registerButton.leading = baseView.leading
registerButton.trailing = baseView.trailing
registerButton.bottom = baseView.bottom
registerLabel.height = baseView.height * (1/8)
With this approach your icons size also decrease and increase relatively with height of view and all the page will be filled.
baseView is view of controller.
What is happening here, you kept the width according to superview ie phone width, but your height is fixed.
Do one thing instead of giving Height constraint, use aspect ration in combination with leading , trailing and top constraint. When view will stretch widthwise , your component's height will also Increase and fill the extra space for iphone 6.
This is the best thing you can do keeping the same layout and design pattern.
Seems you have given some fixed height in views.
As every element is depends on it above and below elements constraints, this might be possible of empty space.
So try to divide the View part then the dependency of constraints will reduce.
If you don't want to show empty space, then use center horizontally to one of the element which will look good, here it may be the third field.
Then start giving same constraints to Register button. Sure it will help you in resolving this issue.
Hey its the best solution for you is stackView
Combine your objects in single stackView.
You can combine your object vertically and also horizontally.
It will decrease your space and view will arranged in awesome manner.
You can select your objects like this.
Click here to make it stack.
Now you can reduce your space like this.

What is the optimal way to align buttons and text? Basic, but necessary due to misinformation online

I've seen a lot of different topics and suggestions on aligning and inputting buttons/text, but the ways I've seen seem kind of risky.
What is the optimal way, for example, to add two buttons, stack them together, and have them be 10% from the bottom of the screen, and centered horizontally on all devices?
Learn Auto Layout if you haven't yet. Use constraints for achieving the following:
For centrally Horizontal on all devices: Use Center X with SuperView.
For having them 10% from bottom, use multiplier value say 0.10 .
The optimal way would be using storyboard for implementation and use of constraints in a proper way.
For example, as you suggested you want bottom space to be 10% of device height so it can be done with the multiplier in constraints also the horizontal center can be easily done with the same, so you could look for a good tutorial of Auto Layout and constraints for better understanding.
Use your Storyboard and add Auto Layout to your elements. Here is an example:
I have added auto layout
Left
Right
Top
Bottom
If I want to change the distance between the buttons, I just choose the auto layout constraint that I have created between the buttons and changes the constant value to it.
If I say that "Button 4" constant to the top shall be 40, then it´s always 40 no matter what size the phone has. If I change the constant between the buttons to 10 then it´s the same for all sizes.
Your best bet is to use Auto Layout. It takes a bit of learning but once you get used to it you can add constraints pretty quickly and easily in Interface Builder. I can't recommend any particular guide but there are a lot of good ones to be found with a quick Internet search.
Here is an example of constraints that seem to be what you are looking for:
For iOS 9, an even simpler Auto Layout approach would be to use UIStackView.
As you can see, no constraints are needed for the buttons embedded in the stack view, as the stack view lays out the buttons for you. All you have to constrain is the location of the stack view itself.
Here's an example of two vertically stacked buttons, 10% from the bottom of the screen, and centered horizontally for all devices.

Vertically spread/spaced screen elements using Autolayout and Interface Builder

I have a relatively simple portrait-only UI, laid out in a Storyboard, with items which I want to vertically spread to fill both 3.5 inch and 4 inch screens.
In other words, I want the spacing between the controls to be adjusted so that the UI nicely fills the screen, irrespective of the screen form factor.
This doesn't seem like an unusual thing to want to do, however I just can't get Interface Builder (within Xcode 5) to add the right constraints - I only seem to be able to get it to add fixed vertical space constraints, which do not adjust for different screen sizes.
Does anyone know how to do this without resorting to programmatic UI construction? I've invested a lot of effort in getting the Storyboard-based UI just right.
The solution needs to work on both iOS 6 and 7. Thanks!
How to do this depends on exactly what kind of adjustment you want when the screen size changes. One way to do it to give the top and bottom most views vertical spacing constraints to the top and bottom of the superview, respectively. Add a view, I usually use a UILabel with no text, in between all the views you have stacked vertically, and give them equal heights to one another. Give one of those "spacer" views a fixed height, but edit it so its priority is less than 1000 (which means it's not mandatory that it be satisfied). Then add spacing constraints between each nearest neighbor above and below each "real" view and the "spacers", so that you have all the views from top to bottom connected together by vertical spacing constraints. When the screen size changes, the only thing that can change will be the height of the "spacers", since the priority is less than 1000, and all other constraints are mandatory. My constraints look like this:
The labels each have the standard (8 point) spacing to the "real" views above and below them. The top and bottom views should have whatever spacing you want to the screen edges.
Apple have now posted a document which describes the officially-endorsed approach to solving this problem:
https://developer.apple.com/library/ios/documentation/userexperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html#//apple_ref/doc/uid/TP40010853-CH5-SW8
Summary of the approach: insert spacer views between your controls, which have equal width/height (as applicable) constraints.

Resources