Xcode - Constraints on iPad - Landscape vs Portrait - ios

I can't seem to figure out constraints and auto layout.How can I have the spacing between two objects be different on the iPad when in landscape and portrait.
I placed to UIViews side by side. When in portrait I would like the spacing between them to be 40 but when in landscape it can be larger because there is more width.
This is what it looks like in portrait mode. Which I am happy with.
And here it is in landscape. As you can see it doesn't seem to fill the screen as well and there ends up being a lot of empty space.
Any suggestions? Thank you!

you can click the small + icon next to the constraint value and select different values for another size class.
or you can change the constraint value in code depending on your orientation.
or you can add extra constraints with lower priority and then increase the priority once you are in landscape mode.

Instead of giving the spacing constraint a constant value like 40, make it a proportional width constraint that is some small percentage of the width of one of the views it is installed between, or a small percentage of the width of the overall superview. That way, as the width of the screen gets larger (as in landscape orientation), the spacing proportionately gets wider as well.

In addition to #Daniel Hall's answer, I would also like to point out that you could also pin the leading and trailing edges of the two UIView you have to their parent view and each other.
For example:
First UIView: Leading Edge 10 points from parent view, Trailing Edge 40 points from second UIView
Second UIView: Leading Edge 40 points from first UIView, Trailing Edge 10 points from parent view
It should resize itself based on these auto layout constraints once you rotate your device. Of course with this method, you run the risk of having your two UIView stretched beyond accurate proportion, so use it wisely.

I ended up having to pin it to the to the bottom and their respective sides.
View 1:
Leading: 30
Bottom: 25
View 2:
Trailing: 30
Bottom: 25
I used a >= constraint for the space between them (>= 5). If I increased the constant on any of these constraints the views would overlap. It's not the best situation because I still have a lot of empty space in landscape mode but it's the best I could come up with.

Related

Constraints to resize buttons to fit any screen - Xcode swift

I don't really understand constraints and have tried many different suggestions found online. All they seem to do is bunch everything up on top of one another or do nothing at all.
I have the following IPad application but I want it to work on any size device, mainly a IPod touch.
The page is simply two buttons that I want to remain the same no matter what screen they're on.
Any help on this appreciated.
It helps to think about points of reference that won't change with different screen sizes. Sometimes you want things on, say the top left corner so you just do constraints to the top and the left.
I'll give you two suggestions
Suggestion One
For your case, it seems like you might want to do constraints off centerY since you want them to be in the middle despite the screen size.
So I would make a constraint to "Center Vertically in Container" and then tap on the constraint and adjust it's value to negative or positive, so that way it's always X pixels above or below the centerY.
Now that's not going to be enough. it knows it's Y position but it doesn't know its height, width, or X position. So you need to add enough constraints to satisfy those.
A few examples:
X/Width: Two constraints to leading and trailing on each button OR Center horizontally and fixed width constraint. (again be careful with fixed width constraints since screen sizes can change, sometimes it's what you want though)
Height: Yeah just give it a height constraint in this case.
Note that this means no matter the screen size they'll always have the same gap between them (and maybe different gaps to the other edges).
Suggestion Two
Use a container view, either a stack view (fill, equal spacing, vertical alignment, a spacing value for gap between) or normal view.
You can make the view a fixed height based off the height and spacing between the buttons you want. Then simply center that container view horizontally and vertically on the super view.
Nonsuggestion
There are certainly other ways (like using buffer views with equal heights constraints. So you'd have an invisible view on top, a view in between and a view on bottom. and you'd give those equal heights constraints and align the buttons to the edges of the invisible views surrounding them. As long as you gave the buttons a fixed height this would work for vertical constraints) but I think these two would probably be the best.

Regular / Regular position sizing constraints for all iPads, including iPad pro?

I've used multipliers in my constraints, to size my views. However in my constraints for position I've used values, which I change for different sizing classes.
However using regular / regular sizing classes for iPad Pro it's positions values aren't big enough, but for other iPads it's fine.
I seriously don't have to add positioning views with multipliers to provide percentage spaces for all my views as well do I?
Right, you don't have to use multipliers because Any value other than
1 creates a proportional constraint. For a Width attribute, for
example, the width of the first item can be set to be twice the
width of the second item
First thing I like to say that the resolution of ipad and ipad pro have abundant difference so in case of yours to add positioning views I just suggest you to use size class and use of priority, constant and relation (less than or equal, equal, greater than or equal) if necessary.
Hope, It'll helpful for you...
What we're after is to set the margin between the top of the screen and the top of the subview with relation to the size of the screen. This means the constraint must be related to the superview's height.
Trying to set the distance between the two views (In the traditional sense) is actually a bad idea in this case. Instead, try this.
Add a constraint to center your view vertically in the superview. Now, open up the constraint in the size inspector (The right toolbar).
If you set the multiplier to 0.01 (0 just puts it back in the center of the screen), your view will go past the top of the screen. Change the first item from Center Y to Top. Now your view will be at the top!
From here, you can change the constant to move your view down a fixed amount and change the multiplier to move your view down further proportionally to the screen's height. The formula would look like
subViewYPosition = constant + (superviewHeight * multiplier)
You will need to adjust the constant and multiplier to suit your needs, but I believe this is a good solution to the problem.
An example of this is shown below.

Auto Layout: Square Image View with equal width / height

The title might seem a bit complicated so I'll just show you what I want in some pictures.
So here is what I want:
[1] - http://i.stack.imgur.com/5Vckr.png
And here is how I tried to accomplish it in xCode 6:
[2] - http://i.stack.imgur.com/ags9s.png
[3] - http://i.stack.imgur.com/UhIuy.png
As you can see I tried to use size classes to snap the ImageView to the left and right in portrait view and to the bottom and top in landscape.
But somehow it is not aligned right in Landscape and if I look at a iPad preview the ImageView does not show up at all.
This probably is pretty simple but I tried for hours and still have no result.
Thank you for your help!
First of all switch mode from w:Compact/h:Any to w:Any/h:Any.
By adding constraints in this mode you will apply them for all devices and orientations.
Here is list of constraints that you need to apply:
Set lower priority (e.g. 750) for the two constraints with the dashed border (Equal Width and Equal Height to superview), and let the others have default priority of 1000.

iOS autolayout with size classes does not differenciate landscape for 3"5 and 4"?

here's what I've been struggling with for the past hours.
I have a view controller that contains a few labels, a picture, and a tableview. I'm using autolayout/size classes in order to use only one storyboard for the various devices supported (meaning: all size of iphones and iPad).
Noew everything is working, except one thing : the settings in "width compact x height compact" are used for 3"5 and 4" iPhones in landscape. So either I say that the table view takes 480px and there's a whole lot of space on iPhones 5/5S, either I set it at 480px but then I cannot reliably align items vertically in my cells.
How come there is no way to say "this view should always takes the full width" ?
Any solution, even workaround, would do. Thanks a lot for your time !
There is no distinction in size classes between 3.5", 4" and 4.7" devices. They all have the same size classes deviced for horizontal and vertical, and behave the same way on rotation.
You can define a view to take all the available space. Explicitly set the bottom and top views to be attached to bottom and top edges (respectively) with constraints, and set the middle view (in your case, the table view) to take all the space in the middle by setting constraints on top with the top views, and constraints on bottom with the bottom views. Now, because top view is attached to top and bottom is attached to bottom, you will have the middle view grow and shrink as needed.
There are a couple of ways to get percentage based sizing.
Link the width of your target element to the width of another element.
Pin your element to its Superview and use the Multiplier setting instead of Constant.
Say you want to set a TitleLabel to have a relative width compared to another element.
Example for method 1:
Ctrl + drag from TitleLabel to another Target element (such as its Parent View), then choose Equal Widths, you can then change the Multiplier field in your Constraints settings to 0.5 if you want 50% width.
Example for method 2:
Pin the appropriate edges of TitleLabel to either the Center, Bottom or Trailing edges* of its Superview (Editor -> Pin -> X Space to Superview).
In the Constraints Settings, make sure you have TitleLabel in the First Item field, and the Superview as the Second Item.
*because the Top/Leading edge of the Superview will have a 0 value, a multiplier against these won't work, as 0 x 0 = 0.
I found method #1 doesn't work well in Table Views, so you may have more luck with #2.

Working with AutoLayout in Portrait and Landscape

Auto Layout, as good as it is, driving me crazy with constraints. I have the portrait mode designed in IB but I can't get the desired landscape orientation to work.
Notice that when the orientation changes to landscape, the spacing between the UIImageView blocks decreases and the text alignment of SAMPLE TEXT changes to right aligned.
Currently, I have added a few constraints for it to work. However, I need to keep the space between UIImageView blocks fixed, as a result of which it looks cramped up in portrait and fine in landscape. I need it to be spread out evenly in portrait and compress in landscape (like in image above). Similarly, currently my constraints bring up the text but it doesnot keep it at the center of screen and right aligned.
Is this possible at all with Auto Layout? If so, how? Help greatly appreciated.
There are several ways to approach this. One way is to enclose your 3 image views in a UIView. Give the top and bottom image views constraints to the top and bottom respectively, and give the middle one a centerY constraint. Give this enclosing view a fixed height and width, and a constraint to the top of the controller's view. Make an IBOutlet to the height constraint for this enclosing view, and change it on rotation. In the example below, I gave it a height of 350 in portrait:
-(void)updateViewConstraints {
[super updateViewConstraints];
if (self.view.bounds.size.height < self.view.bounds.size.width) {
self.heightCon.constant = self.view.bounds.size.height;
}else{
self.heightCon.constant = 350;
}
}
As for the label, the easiest way is to remove the constraints you have (bottom and centerX), and add trailing and centerY on rotation.
Yes, it can be done with Auto Layout. If you want the spacing between views to increase and/or decrease depending on orientation, you can use the Less Than or Equal or Greater Than or Equal relation (instead of Equal) for the constraint, which allows a distance to grow or shrink:
Play around with that and you should be able to get what you want.
Yes, it is definitely possible to do this with Auto Layout. Through a series of steps, that I think might be too long to post as an answer, you can retain the spacing between your ImageViews and keep the alignment of the text the same.
Essentially, you will have to pin a corner of each ImageView and remove some constraints so that it doesn't automatically compress the spacing when you change the orientation.
Full explanation on how to do this (pretty much exactly what you are asking for) is explained in this tuorial. You can find it about halfway through the page.
Hope this is what you were looking for.

Resources