iOS view positioning depending on screen size using constraints - ios

I have been reading documentation/tutorials and playing around with constraints in Xcode and still can achieve what I need.
The issue is that I need to position views (labels, images) and spread them vertically depending on the screen size of the device (focusing on iPhone for now). The css equivalent would be to use margins with percentages.
The labels/images, images don't need to grow or shrink.
As an example I have this in my Interface Builder.
To illustrate the problem I have constraints from top to bottom as follows:
Top image has a "Vertical Space Constraint" (or Top Space) to the "Top Layout Guide.Bottom" of 63
The "Membership" label has "Top Space" of 32
The Membership # has "Top Space" of 16
The white view has "Top Space" of 32 and bottom of 16
The imageview has "Top Space" of 32
The label has "Top Space" of 32
The button has "Top Space" of 20
This measures are correct for the iPhone 6. Now what I have been trying to achieve is to fit the same information in a smaller screen (iPhone 3.5 and 4 inch) by contracting the constraints values. I've tried using the multiplier but didn't work (or didn't know how to use it properly). I tried adding constraints to wAny hCompact but only worked for one of the constraints (top image to top margin), all the other constraints got overridden.
So this is how it looks in iPhone 6.
And this is how I want it to look in iPhone 4 (3.5 inch).
Thanks in advance.

Okey so in such cases i outlet the NSLayoutConstraints in their corresponding ViewController and i start manipulating them based on the screen size at runtime , usually in the viewWillAppear or viewDidAppear , for your case i will assume some facts and show you a small example :
you want the top constraint of the top image to be 10% of the total height of the view
you want the top constraint of the membership label to be 7% of the total height of the view .
you want the top constraint of the membership hash to be 5% of the total height of the view .
you want the top constraint of the white view to be 7% of the total height of the view and the bottom to be 5% of the total height of the view .
you want the top constraint of the image to be 7% of the total height of the view .
you want the top constraint of the label to be 7% of the total height of the view .
you want the top constraint of the button to be 6% of the total height of the view .
so based on those assumptions i would do the following :
-(void)myLayOutMethod
{
//here you set the percentage of every constraint of the view .
CGFloat screenHeight = self.view.frame.height ;
CGFloat topImageConstraintValue = screenHeight/0.10f ;
CGFloat topMembershipLabelConstraintValue = screenHeight/0.07f ;
CGFloat topMembershipHashConstraintValue = screenHeight/0.05f ;
CGFloat topWhiteViewConstraintValue = screenHeight/0.07f ;
CGFloat bottomWhiteViewConstraintValue = screenHeight/0.05f ;
CGFloat topImageConstraintValue = screenHeight/0.07f ;
CGFloat topLabelConstraintValue = screenHeight/0.07f ;
CGFloat topButtonConstraintValue = screenHeight/0.06 ;
//now you start making changes to those constraints .
self.topImageConstraint.constant = topImageConstraintValue;
self.topMembershipLabelConstraint.constant = topMembershipLabelConstraintValue ;
self.topMembershipHashConstraint.constant = topMembershipHashConstraintValue ;
self.topWhiteViewConstraint.constant = topWhiteViewConstraintValue ;
self.bottomWhiteViewConstraint.constant = bottomWhiteViewConstraintValue ;
self.topImageConstraint.constant = topImageConstraintValue ;
self.topLabelConstraint.constant = topLabelConstraintValue;
self.topButtonConstraint.constant = topButtonConstraintValue ;
[self.view layoutIfNeeded];
}
off course all of these percentages are dummy values you can change them as you want , and another thing making outlets of NSLayoutConstraint is the same as making outlets from any other UIKit control , you simply find the constraint and drag it to your class

Related

How to set auto size text for different screens

My task is to preserve the size and position of the elements inside my cell for different screen resolutions.
I did:
Established constraints for the red and green blocks (UILabels) to
the outer container.
Set the constraint between them equal to 0. It is more priority than the limitation of the red block to the bottom and green to the top.
Set Lines = 0 for these labels.
Set Autoshrink.
As a result, the font size changes on different devices. But there are still a few problems:
How can I remove too large paddings above and below both labels?
How to make them resize evenly?
Now one of the blocks has an advantage over the other, depending on what constraint to make a higher priority. If you make them equal - it also does not work.
(I would like to do everything through Interface Builder)
Screenshot with differing priorities of constraints
My constraints
Paddings and Attributes
You can take advantage of equal height and equal width constraints.
Follow the below steps to make the UILabel spacing same on iPhone 8 and iPhone 4s. This will help you to make it proportional.
1) To achieve this simply select, your label(red), label (green) and the superview (which I think you're its a cell of UICollectionView)
2) We are interested here in keeping the height proportional.
i.e Red Label (80%) and Green Label (20%)
Currently, all heights are equal to superview height i.e height of RedLabel and Greenlabel is equal to 100% of superview.
But the goal is to make it 80% and 20% for red and green label respectively.
So select Red Label height constraint. Here you set the constraint which says's "height of the red label should be 80% of the superviews height".
Similarly for Green Label, set "height of the greeen label such that it's 20% for the superview's height".
Red Label
Green Label
3) Now complete the x and y axis position constraint, which would be straight forward
a) Red Label Leading = Leading edge of superview
b) Red Label Trailing = Trailing edge of superview
c) Red Label Top = Top edge of superview
d) Red Label Bottom = not required (as it has all the required constraint's to justify it's position i.e height = 0.8 * superview and it is top aligned, ex: super view height is 100 , keep this view top aligned with height = 80 )
e) Green Label Leading = Red Label Leading (you have already set this in point "a" no need to set the constraint again for Green label)
f) Green Label Trailing = Red Label Leading (you have already set this in point "b" no need to set the constraint again for Green label)
g) Green label bottom = bottom of superview
h) Green label top = not required (as it has all the required constraint's to justify it's position i.e height = 0.2 * superview and it is bottom aligned, ex: super view height is 100 , keep this view bottom aligned with height = 20 )
This is the final constraint list and the storyboard preview for iPhone 8 and 4s.

Issue when percentage based layout (view equal height and width to Superview by multiplier ) for landscape mode

I want to make a two view which :
In portrait mode:
purple one 60 % height - full width
blue one 40% height-full width to subview.
In landscape mode :
purple one 60 % width and full height
blue one 40 % width and full height
HERE IS WHAT I WANT
First I made purple one equal height to subview and multiplier by 0.6.For blue one I made equal height to subview and multiplier by 0.4.Then I added constraints 0 0 0 to purple one and 0 0 0 to blue one.So that it fits perfectly in portrait mode.
To make this in the landscape I used stack view to make vertical alignment to horizontal.It did not work.It aligned just horizontal by 60 % height of purple one and 40 % for blue one.
I did not find class size to change height and width percentage value in landscape.
Can someone explain me how to do this ?
Thank you so much !
You mean like this?
I did that by using a UIStackView and switching its .axis between .horizontal and .vertical.
If this is iPhone-only, you can configure that change in Interface Builder:
But that won't work on iPad, since you have no size class change when we rotate; you would have to make the swap in code (in viewWillTransition).

Which Constraint we need to make dynamic View height in iOS

As I am new to iOS. So forgive me if it is duplicate or very basic question.
I am taking one View. Approx below is the size .
x : 5 y : 5
Width : 590 Height : 100
and I set constraint it
Top to superView 5
Trailing to superView 5
Leading to superView 5
Now I have one Label which have dynamic Text and the Text is too large.
And the Label Constraint is below
Top to superView 5
Trailing to superView 5
Leading to superView 5
and when i set the background color of the View the color is not set. If the Text is to Long. So how to set the Height of the View and also set background so that it looks clear.
Code :
public override void ViewDidLoad()
{
base.ViewDidLoad();
lbl_one.Text = "This is a long label which have long text inside the writing. This is a long label which have long text inside the writing. This is a long label which have long text inside the writing. This is a long label which have long text inside the writing";
lbl_one.LineBreakMode = UILineBreakMode.WordWrap;
lbl_one.Lines = 0;
view_main.BackgroundColor = UIColor.Red;
}
If I give fix Height then it look like this .
Output :
1. Give the below constraints to your view, height is according to your need. here I'm giving 80.
2. Change the height relationship.
3. Add aUILabel in your above UIview, and give below constraints.
--> leading, top, bottom, trailing to uiview and height i.e. 80.
4. set height relationship as you do with UIView.
5. Change the property of UILabel , Lines to zero
6. Now enjoy with your constraints.
EDIT: Add bottom constraint to your view instead of height constraint.
I don't see and bottom constraint added to UIView, so the view height will be 0.
If you have added the height constraint to UIView, there is a probability that UILablel might be overlapping the UIView, so you are not able to see the background color.
Set the UIView height constraint this will solve your problem
You can also add height or bottom constraint to your UIView.

Autolayout to set six square images

I want to implement autolayout to set six square images that are always be in square even if screen size is changed.
I have tried too many variations but fail to do so.
In attached image i share sample view that autolayout will be applied.
You don't need any view wrappers or other funny business here, you can do it purely within IB or AL constraints between each item. The 'trick' is to think about the relationships between each item and to use both constants and multipliers.
Each square here is 1:1 ratio.
The orange square is 2:1 with to the first yellow square, plus 8 for the padding.
The orange square is pinned to the left, the first yellow square is pinned to the right.
All the other yellow squares are relative width to the first one.
Here's the storyboard file too:
https://www.dropbox.com/s/pk8iwj1beamkxtp/SO_Solution-20151215_2.storyboard?dl=0
Based on a comment, I added one wrapper view to make it easy to apply size classes if you want the entire thing to always be visible. (also makes it easier to drop into another storyboard).
Okay, i'll give you an easy way to achieve this, but this is my implementation, and i'm pretty sure there are a lot of implementations easier.
First, create a empty subview, and add the constraints so the view will always be a square in the top left corner:
Trailing Space to superview >= 0
Trailing Space to superview = 0 #750
Top Space to superview = 0
Left Space to superview = 0
Bottom Space to superview = 0 #750
Bottom Space to superview >= 0
Aspect ratio : 1
Now add in this square the square in the top left corner and the topRightView :
// TopLeftView constraints :
Leading Space to superview = 20
Top Space to superview = 20
Aspect ratio : 1
// TopRightView constraints :
Trailing Space to superview = 20
// Contraints between TopRightView and TopLeftView
Align bottom
Align top
Equal Width
Horizontal spacing = 20
You can now set the ratio between the squares, by setting the multiplier value of the "equal width" constraint. Let's use a 1/3 multiplier.
Let's add the bottomLeftView now. In order to not over constraining our view, we don't need to set a multiplier between the square height and this view height. We know the space on the right of the green square is equal to the space below it, so let's use only spacing and alignement constraints.
// BottomRight constraints:
Bottom Space to superview = 20
// Contraints between BottomLeftView and TopLeftView
Align left
Align right
Vertical spacing = 20
The last view to add is the BottomRightView, and alignment constraints will works well :
// Contraints between BottomRightView and BottomLeftView
Align top
Align bottom
// Contraints between BottomRightView and TopRightView
Align left
Align right
Here we are. Now you just need to add squared subviews in top and bottom of TopRightView, and at left and right of BottomLeftView. You can also change the ratio with a single variable, which would not be possible if you had set a ratio constraint between TopLeftView and BottomLeftView.

How I can use AutoLayout with these UIButtons?

I want to add Custom UIButtons as shown below, with W = 100 and H = 100 , so when I tried to use Equal widths and Equal Height and Aspect ratio from the Constraints window it didn't work great :/
so what i have to do ?
Thanks.

Resources