I'm trying to make "Two Equal-Width Buttons" As it's described in Apple Auto Layout Guide.
https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/ViewswithIntrinsicContentSize.html#//apple_ref/doc/uid/TP40010853-CH13-SW1
And it looks ok in preview of interface builder (Main.storyboard).But when I try to change devices i see that width is different on some devices.
How can i fix that ? How can I make equal width of buttons for all devices by using constraints or another techniques?
Updated Examples:
width is ok
width is not ok
Width is ok
Width is not ok
There is not problem with the width of your buttons. Because of difference of 0.5 point between two buttons, it may not be showing you equal width.
Just check width of both button manually, there may not be difference between them, more than 1 point.
Look at this snapshots:
iPhone 5
iPhone 8
iPhone X
Put your buttons inside a UIStackView horizontal and set distribution attribute to FILL EQUALLY
Look this tutorial for more examples.
Related
i have a question about how to setup constraints in a storyboard with autolayout if I want to guarantee multiscreen support so that all UI-controls are accessible and the UI is not messed up on smaller screen-size devices (IPhone 4s or IPhone SE) when I designing on a bigger screen-size device (IPhone 6). I have a design which is build up on a IPhone 6 (in a sketch-file) which I want to transfer to my storyboard. So in general I want to setup all the view stuff in a storyboard and not via code.
Here are my constraints. The button to the bottom has fixed height of 48 and a leadingMargin to the right and left and a vertical distance of 100 to the bottom. The top button has the equal height to the bottom button and a distance of 28 to the bottom button.
Here is the designed View with the mentioned buttons on an IPhone 6. This is the default size where I want to setup the storyboard cause of the sketch file.
Here is the View on an IPhone 4s
As you can see the buttons are to close to the middle cause of the fixed vertical distance and the fixed height. I mean this is obviously cause of the fixed values. So I made some research about percentage position like mentioned here but is this the correct way? Also other ways looks so complicated to me. How can I prevent fixed values like the height and the vertical distance? Is there a way to set the fixed height of 48 for the IPhone 6 and then scale the button down (for IPhone SE) in regards to the screen size (the same for the bottom vertical distance and other fixed values)?
Can someone give me any advice how I can proceed here?
It is a bit complicated I try to explain it as much as I can.
Note: Auto-layout is just like constructing a building every thing step by step.
Select top button and add these constraints (Leading:8,Trailing:8, And select Aspect Ratio checkbox) + And also add "Horizontal center and Vertical center constraints" select the vertical center constraint and change it's multiplier to 1.5 or increase or decrease it's value accordingly.
There should no error after this only warnings if any.
Select second button and add Top constraint to 8. Select both buttons and add constraints which are highlighted in screen short.
Run and check on different screens. Hope it help.
bottomButton.bottom = superview.bottom * 0.9
OR
Change the bottom constraint by code
bottomConstraint.constant = xx
self.view.layoutIfNeeded()
I've got all my elements in the view and have added constraints to position them correctly on any device.
But when it's run on a 3.5 inch iPhone some of the bottom stuff is cut off and when it's run on a iPhone 6Plus there's a lot of extra space on the bottom.
How could I resize all the elements to look good on all devices?
This is a universal app to run on iPhone and iPad.
I guess you constraint an element as width equals 300...It's very bad for some elements that should fill (or fill percent of) the screen. I suggest you make percentage constraints. For example, make equal width to view, click Edit button and set Multipiler 0.6. It looks like this in storyboard:
make two constraints (trailing and leading for example) and make aspect ratio for your image, maybe this will help you.
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.
The auto layout "picker" looks like the image bellow:
But what if I only want to target iphone 6 plus and Ipad?
I use the constraints compact width | any height in order to only target 3.5 - 4.7" displays.
But what should I use in order to only target iphone 6 plus / ipad? - The any width | any height do target them but would that not also overwrite the rules set in compact width | any height ?
What I want to do is to increase spacing between three labels when the app runs on a iphone 6 plus or ipad. Also to note, my app only runs in portrait mode if that matters.
thanks in advance,
You shouldn't categorize autolayout via device, but rather by class sizes. This was a HUGE emphasis this year at WWDC due to the new iOS 9 iPad multitasking feature discussed at the keynote.
I recommend trying the following idea for your layout. Note this is just a visual interpretation of what you need to implement in IB.
All three labels have equal width constraint
|---[first label, maxwidth = x]--[second label]--[third label]---|
This will make all three labels have the same width and be evenly spaced across. This approach helps with all class sizes of compact width | compact height, etc. If you need help finding a way to do even spacing between, trying adding filler views:
|[uiview][first label, maxwidth = x][uiview][second label][uiview][third label][uiview]|
Each [uiview] in this case will have the same width as well with a background color of clear this way the margining between the labels will be even and these views aren't "seen" but help with autolayout.
If you need help with this auto layout implementation please let me know in the comments.
I am a little bit confused by Xcode 6 Storyboard.
The auto layout seems to be a very powerful tool to build UI for different devices. However, no matter what kinds of layout I chose (compact or any height/width) or even uncheck the "Use auto layout" and "Use size classes", what I mapped in the storyboard view always looks different when I am testing (using an iPhone 6).
For example if I left a UIButton at the center of the storyboard, it will be a little right down away from center when appears on my iPhone 6.
Could anyone please give me some help on this. Maybe just for iPhone6 instead of different devices. Thank you very much.
If you simply want to center an UI element check both Horizontal Center in Container and Vertical Center in Container in the storyboard constraints alignment popover.
The reason, you are having this issue is the mis-matched stimulator size. For example, the apple standard for iPhone 6 is a frame of 400 x 600 pt, meaning 2:3. So,
First, turn on the auto Layout and size classes. Then change "wAny hAny" to "compact hAny".
If, you change the Stimulated Size now, you will se the width as 400 and height as 600.
After this you need to add the UIButton at the centre and even without adding any constrain, you will see your button to be centered in the frame.