Gravity in iOS like in android - ios

Is there any easy way to center controls in a view in iOS like using android:gravity="center_horizontal" in android? I could calculate the position for each control before adding it and recalculate when the screen is rotated, but I'm wondering if there is a better solution for this.

Please pay attention, layout_gravity is different from gravity in Android.
layout_gravity is for the alignment in container view and gravity for the content alignment in self.
After reading your question, I think you mean layout_gravity not gravity.
Okay, Let's discuss about UIStackView.
What is UIStackView ,as the documentation said , it is just a container view which can control the distribution, aligment, spacing ,xxx on its subviews, and is created with autoLayout, it means you don't need to manage those constraints on the subviews.
As you see, the alignment of stackView will apply to all the controls on it not single one.
To achieve the effect like layout_gravity , you have to manage the constraints manually .
and the constraints on the center button .

Related

How to use auto layout so my app fits all screen sizes in swift?

I need my buttons to stay in the same positions for all phones.
I want it to look like this on all iPhones:
But when I switch to a larger size phone it does this, it also looks ugly on smaller phones as well:
That is a VERY broad question, as a lot of iOS UI depends on autolayout. I suggest you work through these tuts at at least AutoLayout. From your screen shots, it looks as if you have set a width constraint on your view with the green background instead of pinning the leading, trailing, top, and bottom to the edges.
Auto layout is, in essence, a system that performs calculations based on constraints. This means that to perform what you want, you need to add constraints to each of your objects so that the compiler knows how you want to resize your UI. But like others have said, that is a very general question. I suggest looking into the topic a bit before asking, so you can narrow down your question and get better answers.
You need to define positions for all your button or views. You need to define atleast 4 constraints for all your view. By adding constraints you tell your views where they should be placed on all screens. You define their positioning with respect to screen by adding constraints.
When you add trailing, from top and width and height constraint you tell that view should be placed in fixed position i.e. x , y and occupy defined space whatever may be screen size.You can opt for fixed width or height. Instead of fixing height and width you can also define leading or trailing constraints for the view. Constraints will adjust views frame according to screen size.
For beginning you can opt for some tutorials available online. You can check Raywanderlich here. Hope it helps.

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.

What should I do to make generic size of all UI controls in iOS?

I was trying to practice Auto Layout in iOS, and I started with very simple UI. Please see image for understanding my problem.
All the text files are in middle of screen (I have deliberately kept on guide line), still you can see in preview, controls are not fully shown. I have not chosen specific size. Size is 'Inferred' still I am not able to see all the controls on UI.
I tried both adding and removing Auto Layout, but no luck. What should I do to create generic UI which will work with all the sizes of iPhone and iPad.
This image is without use of Auto Layout.
After enable autolayout and size classes you have to apply autolayout constraints.
Autolayout is a detail topic. Few basic things when applying autolayout is:
UI element need four constraints.
position x
Position y
height
width
So you will select first label (Number 1). Then press control and drag to superview. You will be provide options. Select Leading space (This will handle x position)
This is the way you can press control and drag:
http://www.appcoda.com/wp-content/uploads/2014/07/auto-layout-login-trailing.gif
Go to size inspector. You can see the constraint.
Press edit and change its value to 25(for test).
similarly control and drag again to superview and select Top space. (This will set y position for label)
This is simple way for the above taken from AppCoda
http://www.appcoda.com/wp-content/uploads/2014/07/auto-layout-control-drag.gif
You can change the value of these constraints according to your need.
UILabel and uitextfield get width and height from their content size. So don't need width and height constraints.
Now when you preview on any device this label will be stick on top left side of screen.
So this is a complete mechanism. You have to apply constraint to every ui element.
Below is a link to very comprehensive tutorial by
http://www.raywenderlich.com/115440/auto-layout-tutorial-in-ios-9-part-1-getting-started-2
At start this tutorial tried to create three views using autolayout. At the end it shows very similar scenario like yours by applying constraints to button and labels.
The problem here is that your constraints are not set correctly to work with every size of iPhone and iPad. You are setting the leading edge constraint to be a fixed size from your view controller's view to the subviews.
The simplest way to solve this issue would be to have a container view that you center in the view controller's view and then use constraints to set 'Center X Alignment Constraint' and 'Center Y Alignment Constraint' to set the container view's center to that of the view controller and then add your subviews to the container view.
As a side note auto layout has a reputation of being hard to learn, you have to put the time in to learn it, I would start with Apple's Auto Layout Guide.

Swift: centering a label with another control in the way

I'm wondering if I can move a label to the center of a view even if there are other hidden controls in the way. I'm using Swift 1.2 and I'm using auto-layout for the initial position.
So I really have two questions:
How can I move a label to the center? I've found plenty of examples of moving to a particular location based on the original position. I just want the center. I tried this:
self.labelTest.center = self.view.center
Will it work 'over' hidden controls or do I have to move them too? i.e., to get them out of the way
Thanks
self.labelTest.center = self.view.center
This instruction won't be affected by the existence of any other views on your self.view if autolayout is off. However if autolayout is enabled depending on what constraints you've set they may interfere with the positioning of your views. So either turn off AutoLayout or ensure the constraints don't hinder your view being centered.

How can I use constraints AutoLayout with to specify a different layout on landscape vs. portrait without using code?

I have an iPad app that features a login screen, with the login controls contained within a UIView.
When the iPad is in portrait orientation I have the Login UIView near the bottom and center of the app, pretty much right above where the keyboard will be, and the company logo is in a UIImageView centered across the top. I'm using AutoLayout constraints to keep the company logo gravitated to the top and right, and the Login UIView gravitated to the bottom and right.
(source: chattypics.com)
When I rotate this to landscape, the effect is something like this:
(source: chattypics.com)
I want it to look like this
(source: chattypics.com)
So, I want the two elements to be side-by-side, and I want the Login UIView to be further to the right. The amount of spacing to the right of the UIView when in portrait mode is greater than I want for landscape mode, and the distance from the bottom is less than I want for Landscape mode. I could handle this via "center in container" instead, but that would also not work in Landscape mode.
I've used the technique detailed in this post to make things be "side by side" when in landscape mode, but I don't believe it will suffice here because I want the layouts within the "views" to also be different on rotation.
I can think of ways to pull this off programmatically, but I can't imagine this is all that unique a need, so is there some way using just constraints in IB to pull this off? Some "this is what constraints in IB were designed for" way, possibly dealing with priorities? Or do I just need to pull this off in code?
You could achieve such behaviour using different priorities for constraints in Interface Builder. For both views ("Company Logo" and "Login view") you need to set up "vertical center in container" and "horizontal center in container" constraints with some reduced priority.
Next you need to defined "Vertical Space" and "horizontal space" constraints using rules with relations like "Less Than or Equal".
I've achieved such behaviour just using Interface Builder.
Screencast demonstrating this in action.
Source code on Github (I've set it up in iPhone only storyboard, but the idea is similar for iPad).
Also you could combine "less than or equal" with "greater than or equal" using different priorities to achieve best result.
instead of repositioning the elements, it looks like you just need to rotate them individually. Set them up in a container view, center the container view in the view controllers view. Then just set up the distance between the two views and setup the autorotation on them.

Resources