Auto contraints seems like a bit of a chore. I have a bunch of elements in my main view (this is a single-view app) inside Main.storyboard. So imagine a few labels, buttons, controls, etc.
For example, take one label that says "Hello World" that's centered horizontally in the upper portion of the screen.
I need to add the following constraints to make it appear "normal" in my various devices ipad/iphone:
Horizontal Center constraint
Leading Space
Top Space
Trailing Space
It works, but it seems like a lot of work, I don't remember doing this work in the good old days (~3 years ago) with struts and springs. So I need to add all these constraints to each of my other elements too. So if I have 10 elements, I need roughly 10x4=40 contraints? Is this the ideal way to do this?
If it were up to me a view and the elements as I place them in the view and all controls in it would just be stretched relatively to fit the size of the device. An example would be like in photoshop, where we just decide what the overall image looks like and then scale the image to just fit the dimensions that we want. Is this possible in xcode?
Note that my app is just portait only - for iphone/ipad, but looks exactly the same in both (ie same layout for the controls)
You don't need to set that many constraints.
Horizontal center + top space would be enough given your example, or leading, trailing and top space.
If you are setting leading, trailing and horizontal center, you are over-specifying in that axis and possibly giving the auto-layout system contradictory information that will cause problems.
For that specific example: no, you only need a horizontal center and a top space, because UILabels have an intrinsic content size so their width and height is specified by their content and not constraints (unless you want them to be).
You didn't do this work in the good old days because Auto Layout wasn't on iOS then and there was only one particular possible iPhone size at the time: now there are 4. Auto Layout is an essential tool for modern iOS development.
As for controls stretching relatively to the device size, it depends on the control, but in general standard controls maintain the 44 point touch target rule - for example nav bars have gotten wider to accommodate wider phones but they haven't gotten any taller, because the larger screen size should be used to display more content instead of more chrome.
But yes, if you wanted to have controls have particular dimensions based on device size that is definitely possible with Auto Layout.
Related
I would like to center four buttons horizontally and vertically. Each of the buttons shall get a background image later, so I think it's important that the aspect ratio stays more or less the same, otherwise the pictures won't fit onto the button.
A screenshot of what it should look like:
All buttons have the same size and should take up as much space as available (small margin, 10px or so, not more if possible). I don't know how to set the constraints that the application looks good on all devices (iPhone 5s and iPad 10.5").
The application must not necessarily run in all orientation modes.
How do I have to set the constraints?
This problem can easily be reduced to the problem of making a maximum square centered in its superview. You can do that easily with just four constraints:
The rest — the grid of buttons — just falls into your lap. For example, make my blue view a UIStackView containing a two UIStackViews, and there's your grid. Or you could do it with explicit constraints yourself.
If this app can rotate, you might need two sets of constraints, one for when the width is less than the height, the other for when the height is less than the width. You would then have to swap them in code. But that's another issue, and is not difficult.
Add them to UIStackView, for placing them horisontally use horisontal value for axis property you can customize it with distribution, alignment and other properties of UIStackView.
It's the easiest way
I'm struggling a bit with constraints on iOS with the differents screens sizes nowadays.
I tried google and stackoverflow to find a solution but my english does not seem fluent enough to find an answer.
I got 4 buttons verticaly aligned, the first and the last one are constrained by the edges of screens (kinda easy). But I'm really struggling with the constrains of the 2 middle buttons. I can't find a way to make them equally spaced from the left and right buttons on every size screens.
Is there something easy and tricky to make these constraints right ? Or am I doing it wrong and should I try to do it programmaticaly ?
Thanks
Add three invisible views in middle of each button, make their width equal with each other with constraint then your four buttons will be equally spaced. For the Y then you just need to pin it at your desired place.
If you are going to support only iOS 9 and higher, then use a UIStackView.
The solutions to this problem is very simple. This can be solved using the concept of "spacer views". You have to place invisible views between each red coloured view. You would be requiring 3 in your case. Then make their background as clear colour. .
Next, make their width equal and constrain their edges to the views that are after and before that view. You then define the size for red coloured view.
REMEMBER dont give the "clear coloured views" any fixed width. It would be determined by the runtime.This would solve the problem. Tell me if any more information is required.
Here is a blog post for the solution for this
http://adamdelong.com/fluid-layouts-with-auto-layout-size-classes-spacer-views-and-constraint-priorities/
This is the youtube video for this
https://www.youtube.com/watch?v=eSG-3-QpmWk&feature=youtu.be
Besides Tj3n's answer with views between buttons, you could use
A UIStackView (iOS 9!) where you use for settings Axis: horizontal, Distribution: equal spacing
A Toolbar (depends on what you want to do with your buttons) with toolbar items and flexible Space between them
Why not size classes? Apple introduced the concept of adaptive user interfaces in iOS 8 relying on a combination of Auto Layout and size classes.
If you aren't aware of what is size classes, there are plenty of tutorials available, please find one.
Summary: Apple very cleverly removed two story borads for iphone and ipad and made a single story board for universal app. No you dont have to struggle trying to apply autolayout constraint that satisfies all the screen sizes :)
Below are few of the size classes and their meaning :)
Regular width x Regular Height ----> iPad Potrait mode/ipad landscape mode
Compact width x Regular Height ----> iPhone 6 plus,iPhone 6,iPhone 5s,iPhone 5,iPhone 4s potrait mode
Compact width X Compact Height ----> iPhone 6,iPhone 5s,iPhone 5,iPhone 4s landscape mode
Regular width x Compact Height ----> iphone 6 plus landscape mode.
You can select the size classes you want to support from story board :) and start applying constraints specific to each size classes (like buttons in middle) or if you have generic one (like your buttons fixed to screen) for all the size classes.
You can deploy, remove, reuse or delete the constraints form various size classes.
SUMMARY: Buddy, If you are not using size class yet, its a high time to start using it :) There is a wonderful video on it in apple WWDC sessions 2014 i believe. Download, watch, start playing with it.
Happy coding :)
you can use equations to get this appearance.
use views' trailing points to get this.
View1.trailing = superview.trailing*(2.0f/9.0f)
View2.trailing = superview.trailing*(4.0f/9.0f)
View3.trailing = superview.trailing*(6.0f/9.0f)
View4.trailing = superview.trailing*(8.0f/9.0f)
if you make View1.width = superview.width*(1/9.0f) you can achieve what you want.
there are a lot of similar solutions for this issue. but the base is using trailing points.
It may also be done with using centerX positions of Views.
View1.centerX = superview.trailing*(3.0f/15.0f)
View2.centerX = superview.trailing*(6.0f/15.0f)
View3.centerX = superview.trailing*(9.0f/15.0f)
View4.centerX = superview.trailing*(12.0f/15.0f)
Thanks to LearneriOS answer, I solved my problem.
In order to get my wished result, I created 3 views with 10 width.
My first and my last button were already constrained. I constrained my first extra view to my first button with Horizontal spacing then i constrained my first extra view with the Center vertically in container. I then constrained my extra view to his own width and heights.
There come the important part: I did go on the constraint menus and selected the width constraint. The value inside was still 10 but I did change the priority from 1000 to 750.
Then I did copy my first extra view and constrained all of them to the nearest buttons, the same way I did with my first entra view but I removed their width constraint (to all the extra views but the first one) and constrained the extra views with the first one by plugging the: Equals Width.
Then I got my result, I hope it was clear enough and thanks again.
I have an app which I've designed in the width:any height:any universal size template in XCode (Swift). Basically, I have a custom cell, with its own uitableviewcell class too, and two labels inside of it which display array data. Anyway, I am struggling to add the correct restraints etc, so that the labels and text inside them display properly on all iOS devices. Even though I have changed the font to be able to go to 0.2 scale, there's still sometimes overlap or text clipped in the label on smaller iOS screens. It's probably a simple thing to resolve. So can anyone help me make this layout look the same, or the equivalent, on all iOS devices and all orientations too please? Here is my design:
The fact that your labels are overlapping each other is probably that you don't have the proper width constraints.
This is what I will do, taking the left label as an example:
add constraints to the left, top, bottom margin
add a width constraint to the parent view and making it 50% of the parent width
You will need to do the similar for the right label replacing the left margin constraint with a right margin one.
Now both the labels only take 50% of the width, then they will not overlap any more guaranteed.
I'm a bit stuck and any help would be greatly appreciated!
I'll give you a quick overview. I have designs for a screen that were built in sketch using an iphone 6 screen size, then redesigned to fit and look right for an iphone 5/5s/5c, and 6 plus as those are the only devices that I want to support.
But the design portion or implementing the designs for just one specific screen size is easy and I understand that part. Where am I'm lost completely, is how to implement a design in one view controller that looks the way that it should in all the screen sizes I designed for.
I've gone through more than a few auto layout and size class tutorials and not sure how I properly use them so that the app recognizes "this is an iphone 5, use these image sizing and placements instead, and this is an iphone 6 plus, use these" and so on.
Everything I've seen to this point regarding auto layout and constraints only use 1 set of numbers to judge distance from elements for example, but all screen sizes would have different distances.
What am I missing or not understanding? I know I'm looking at something improperly.
Thanks in advance for all help!
You're correct that just one set of numbers could be used to judge distances, but this can still describe how a view should appear on different screen sizes. Your problem may be that you're thinking of constraints as describing the frame of your view? (Which obviously has to be different on every device). I find it more helpful to think of constraints as describing how each edge of my view relates to another view.
For example here's a view controller I setup with all the same constraints and how it would look on different devices. The constraints describe how the large grey view is pinned it's left and right edges 20 points from the left and right edges of its container view. It's pinned to 8 points from the top and 8 points from the top of the label. The label is centred vertically and horizontally and it has intrinsic content size. Each button is pinned 20 points from the bottom edge with button 1 and 2 being pinned to the 20 point from the left and right edges respectively.
I don't know if that helped or if that wasn't the answer you were after and you need to arrange your views differently depending on the device: you can tell Xcode which device size and orientation the constraints you're creating are for, using this button in Interface Builder.
Use it to select a device size/orientation. After, any constraints you create will only be used on that device. By default any width and height are selected so normally your constraints are applied to all devices.
Also, you cannot choose which devices you want to support, only the iOS version.
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.