Using Auto Layout in Interface Builder with complex views - ios

So, here's a tricky one. I'm working on a portrait only app that should be compatible with the iPhone 4s, 5/5s/5c and 6/6 Plus. Unfortunately, I'm having some troubles working with Auto Layout in order to make the user interface fully compatible with the previous listed devices.
Here's a screenshot of how the UI should look like (this is from an iPhone 6 Plus that I'm using as a reference for the other screen sizes):
I have a 338x338 points blueCircle, a 180x180 redCircle, a 118x118 greenCircle, a 84x84 purpleCircle and, finally, a 50 points tall adBanner. The result I would like to achieve is to have an iPhone 6 Plus UI that respects these view sizes and a properly shrunk down UI for all the other ones; in addition to that I will let the users pay to remove the advertisement banner on the bottom so I need to resize the UI accordingly too (set circles vertical spacing to the banner and set its height to 0 maybe?). I messed around with Interface Builder and I came out with a decent - not so precise - result. Take a look at the UI on an iPhone 4s screen:
It looks decent but there's major problem. In Interface Builder I'm working on a Freeform ViewController with the same width of an iPhone 6 Plus (414 points) on which I've added all those circle views with the previously listed frame sizes. To make an example, let's temporarily ignore all the other constraints to concentrate on the aspect ratio ones: on the 338x338 blueCircle I've added an aspect ratio constraint, the same on the 180x180 redCircle. Then I've control-dragged from the redCircle to the blueCircle and clicked again on aspect ratio so that it resizes accordingly to the blueCircle. As I said the result wasn't precise since, if I println() redCircle's frame, the console will say that its width equals to 175.666666666667 (instead of 180) points.
Here's the project so you can check it out yourself. I believe its worth more than a thousand words. I'm not very good at Auto Layout and I'm sure I'm creating too many useless constraints. What could I do to improve my layout?

you need to set height and width of all the circle views as proportional to its parent view.
I set the height of blue view as 0.5 proportional to its parent view and its width will be in aspect ration with itself as 1:1
repeat same for all the other views and apply vertical spacing and horizontal spacing as required between views
this is how it looks on iphone 4
this is how it looks on iphone 6 plus

Related

How to scale buttons for different devices

I have buttons on my screen I have attached constraints but on different sizes of screen I don't see my buttons right as I want to. There are the same size on different screens and I can't see all buttons on small screens
Here is a good version of it on iphone 8 plus in xcode
and then I change view to iphone se or any another iphone and I get these troubles:
What do I need to do to have the same screens?
Make the buttons have a width that is in proportion to the view
width.
Then add a 1:1 aspect ratio constant so that the buttons remain
square.
Then position the buttons in relation to the screen dimensions (not
absolutely).
This should get the job done for you.
Setting proportional width
Suppose the main view's dimension is 375 x 667 in interface builder. Suppose you place a 90 x 90 button on it. To make it always have a width in proportion to the main view's width,
Add an equal widths constraint to the superview for the button.
Edit the constraint's multiplier: Change it from 1 to (90/375)
Doing the above makes sure that for different screen widths, the button's width will also change in proportion.
Here are screen shots from iPhone XR and iPhone 5s, that I took from a sample I just did to try this out. As you can see, the buttons stay within the screen and maintain their shape. Hope this helps.
You don't seem to have defined the constraints of the button to superview. eg: left edge, top edge...
*edit: post complaint below #raisedeybrow
You will need to define (add constraints) how far from the edge (left and top, right and bottom) you want your button/s to be. Then apply content hugging and compression priorities on buttons for all of them to scale as you'd like. Some will need to be bigger, some you don't want to allow to shrink etc. Lots to set if you'd want it to look fluid

how to set autolayout for different devices by using storyboard

I have an Iceland map which contains 9 different area buttons. Every button has a different size. I want the map can show the same on different devices. I only know to set the central button with horizontally in container and vertically in container. However, other buttons, no matter how I set the constraints, they will be a mess on iphone SE or iPhone Plus. (I use iphone 8 as normal)
Can anyone teach me how to set the constraints for the 8 left buttons? thank you!
The best thing for this is a vertical UIStackView nested with 3 horizontal stacks
MainStackView constraints
centered vertically & horizentally , width & height propotional to screen
then drop 3 stackViews inside it set axis = horizontal and drop 3 Buttons for every inner stack
Note: distribution is fillEqually for all the stacks , spacing = 10
look to this Demo
Something I've done in the past is used a single control as the anchor for all the others.
Basically this means taking the centre button and anchoring it to the middle of the container view (centre horizontally and vertically)
I then constrain the middle/top and bottom controls to it (vertical space and horizontally centred)
From there each control in the row is then constrained against these elements (horizontal spacing and vertically centred)
You might also consider constraining the sizes to the centre control as well, so all the controls share the same size. For me, this means constraining the width of the control to a set value and then applying an aspect ratio to the height. I do this because then I can change the value of the width constraint and ALL the control will change size
Because iPhone 5s, iPhone, iPhone+, iPhone X all share the same "sizing classes", it makes it some what more difficult (as you can't apply traits - but you can do it for iPad and iPhone ;)).
At this point, I would bind the centre controls width constraint (and the height if you need it) to the source code and when the view is loaded, determine the device screen size and make minor adjustments to the constraints values.
If you would prefer a complete "storyboard" solution, you could constraint the width of the centre control to the super view and apply a modifier
Using the "device" templates from the storyboard, layout one a iPhone 5s and iPad Pro
The long and short of it is, you have "options". You might even consider using UIStackView to define the rows, personally I find it easier to constraint the controls to a central anchor point - but that's my experience and your needs might differ

Laying Out Login Screen In Xcode - iOS

I have a login layout and I want it to work universally on 4 inch, 4.7 and 5.5 inch screens.
I want everything to be as if the screen was "one" and I just made it all x% larger or bigger to stretch and fit the screen.
Part of the challenge in doing this is that different components are adjusted in different ways to scale with screen size, as well as that there are a few ways to do some of those.
Lets look at a few:
You can use Autoresizing to scale a view automatically with with the size of it's superview/container (so this applies to changing from portrait to landscape). You can find this in the size inspector (if you haven't set constraints). You can see an in depth tutorial on it here.
This let's you set both spacing and internal space based on where you place the view originally.
Another way is setting constraints in relationship to another view with a ratio other than 1:1. For example, you can set a constraint of your button to the superview as equal widths and edit that constraint's ratio/multiplier to 1:2 to make it 50% the size or 1:4 to make it 25% of the width, etc'.
For the fonts you should probably use Autoshrink. You can see a detailed answer about this here.

Swift how to resize elements depending on screen size

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.

xcode size class vs actual iphone resolutions

Something still not very clear. We know for example iphone 5s has a resolution of 320 x 568 points.
If on xocde, storyboard I use “wAny hAny” size class and place a VIEW(UIView) sized 500h x 500w and constrain it to the top, left, right and bottom of super view.
In there I can fit 100 50x50 points images, like 10 images per row.
Now if I run this app on the iphone 5 simulator I am not able to see 10 images in a row since the width is only 320?
Maybe iOS will resize the images so they can hit? What if I don’t want those images to be resized?
Can someone please help me with this or guide me to a document that explain this?
The superview will be resized, when the app runs, to fit the screen. So, since you have pinned the view to the top, left, right, and bottom of the superview, it will be resized as well.
It is up to you to take all this resizing into account when you design your interface and add your constraints. The whole point of constraints is to allow you to design in the face of all this resizing.
Thus, as for your 10 images, they will certainly not fit at fixed width 50, 10 to a row, when the app actually runs, because (as I just said) the superview is going to be resized. It is up to you to design the interface and the constraints so that they will fit.

Resources