Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set Autolayout Constraints Relative to Device Size

I fell into the trap of relying on Autolayout. I currently have a ViewController with a ton of UIViews and realized they're distorted on smaller devices (iPhone 4s and 5).

Is it possible to set constraints in Autolayout relative to device size.

For example, I have one UIView with several other UIViews aligned edges. I would like to change the height in Autolayout of that one UIView to equal half the device height.

like image 976
Onichan Avatar asked Mar 21 '15 05:03

Onichan


People also ask

How do I create a constraint in Autolayout?

Control-Dragging ConstraintsIf you drag more or less horizontally, you get options to set the horizontal spacing between the views, and options to vertically align the views. If you drag more or less vertically, you get options to set the vertical spacing, and options to align the views horizontally.

What is Autolayout aspect ratio?

If you select Aspect Ratio for a single item, the width of the item is used as the numerator for the ratio, and the height is used for the denominator. If you select Aspect Ratio for multiple items, Auto Layout chooses the width of one of the items for the numerator and the height of another item for the denominator.

Does Uiimageview have intrinsic content size?

A vanilla UIView instance, for example, does not have an intrinsic content size. This means that you need to add four explicit constraints to describe the size and position of a UIView instance in a user interface.

What is constraint to margin?

By unchecking "constraints to margin", you are adding constraints, meaning your interface will react correctly to changes in size or orientation.


1 Answers

Yes. There is a way to constrain by screen size.

They are called size classes.

In Interface Builder look on the bar at the bottom of the screen where it says wAny hAny, those are pulldowns. Select the combination of height and width of the device and orientation you want to constrain it to, and when you create the constraints in that mode, they'll be specific to that size/orientation. You can also add and modify size-specific constraints in the inspector, constraint editor pane, in Interface Builder.

If you need to tweak some corner case things that you aren't able accomplish conveniently enough with size clases, you can make an IBOutlet for a constraint and refer to it in your code, and modify it when the view appears and changes, similar to the following example. This is much easier and safer than trying to generate constraints from scratch programmatically.

Note: When modifying a NSLayout constraint via an IB outlet, you can only tweak the constant field, not multiplier because multiplier is readonly at runtime. So whatever scaling factor you use (if any) must be multiplied into whatever final value you use for constant.

@IBOutlet var tableYTopConstraint : NSLayoutConstraint!

override func viewWillAppear(animated: Bool) {
     adjustViewLayout(UIScreen.mainScreen().bounds.size)
}

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        adjustViewLayout(size)
}

func adjustViewLayout(size: CGSize) {
    switch(size.width, size.height) {
    case (320, 480):                        // iPhone 4S in portrait
        tableYTopConstraint.constant = 0
    case (480, 320):                        // iPhone 4S in landscape
        tableYTopConstraint.constant = 0
    case (320, 568):                        // iPhone 5/5S in portrait
        tableYTopConstraint.constant = 0
    case (568, 320):                        // iPhone 5/5S in landscape
        tableYTopConstraint.constant = 0
    case (375, 667):                        // iPhone 6 in portrait
        tableYTopConstraint.constant = 0
    case (667, 375):                        // iPhone 6 in landscape
        tableYTopConstraint.constant = 0
    case (414, 736):                        // iPhone 6 Plus in portrait
        tableYTopConstraint.constant = 0
    case (736, 414):                        // iphone 6 Plus in landscape
        tableYTopConstraint.constant = 0
    default:
        break
    }
    view.setNeedsLayout()

}
like image 85
clearlight Avatar answered Sep 28 '22 19:09

clearlight