iOS Autolayout - How to set two different distances between views, depends on the screen height

25,803

Solution 1

You can create an NSLayoutConstraint outlet on your view controller and connect the outlet to the activity indicator's Y constraint in your xib or storyboard. Then, add an updateViewContraints method to your view controller and update the constraint's constant according to the screen size.

connecting constraint to outlet

Here's an example of updateViewConstraints:

- (void)updateViewConstraints {
    [super updateViewConstraints];
    self.activityIndicatorYConstraint.constant =
        [UIScreen mainScreen].bounds.size.height > 480.0f ? 200 : 100;
}

Of course you will want to put in your appropriate values instead of 200 and 100. You might want to define some named constants. Also, don't forget to call [super updateViewConstraints].

Solution 2

The problem of @Rob answer's is you should do a lot of code for each constraint. So to resolve that, just add ConstraintLayout class to your code and modify constraint constant value for the device that you want in the IB :

enter image description here

//
//  LayoutConstraint.swift
//  MyConstraintLayout
//
//  Created by Hamza Ghazouani on 19/05/2016.
//  Copyright © 2016 Hamza Ghazouani. All rights reserved.
//

import UIKit

@IBDesignable
class LayoutConstraint: NSLayoutConstraint {

    @IBInspectable
    var 📱3¨5_insh: CGFloat = 0 {
        didSet {
            if UIScreen.main.bounds.maxY == 480 {
                constant = 📱3¨5_insh
            }
        }
    }

    @IBInspectable
    var 📱4¨0_insh: CGFloat = 0 {
        didSet {
            if UIScreen.main.bounds.maxY == 568 {
                constant = 📱4¨0_insh
            }
        }
    }

    @IBInspectable
    var 📱4¨7_insh: CGFloat = 0 {
        didSet {
            if UIScreen.main.bounds.maxY == 667 {
                constant = 📱4¨7_insh
            }
        }
    }

    @IBInspectable
    var 📱5¨5_insh: CGFloat = 0 {
        didSet {
            if UIScreen.main.bounds.maxY == 736 {
                constant = 📱5¨5_insh
            }
        }
    }
}

Don't forgot to inherit your class constraint from ConstraintLayout I will add the objective-c version soon

Solution 3

The basic tool in Auto Layout to manage UI objects' position is the Constraints. A constraint describes a geometric relationship between two views. For example, you might have a constraint that says: “The right edge of progress bar is connected to the left edge of a lable 40 points of empty space between them.”

This means using AutoLayout you can't do conditional position setting based on UIDevice's mode, rather you can create a view layout which modifies itself if eg. the app runs on 3.5' full screen (IPhone4) or 4' full screen (IPhone5) based on the constraints.

So options for your problem using Constraints:

1) find a view on your layout which can be used to create a constraint to position the progressbar relatively. (select the view and the progressbar using CMD button, then use Editor/Pin/Vertical Spacing menu item to create a vertical constraint between the 2 objects)

2) create an absolute constraint to stick the progressbar's position to screen edge (keeping space) or centrally

I found helpful this tutorial about AutoLayout which might be beneficial for you also: http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2

Pls note: autolayout only works from IOS 6.

Share:
25,803
Daniel
Author by

Daniel

Updated on September 21, 2020

Comments

  • Daniel
    Daniel over 3 years

    I know I'm missing something, because this has to be something easy to achieve.

    My problem is that I have in my "loading screen" (the one that appears right after the splash) an UIImageView with two different images for 3.5" and 4" size screen. In a certain place of that images, I put one UIActivityIndicator, to tell the user that the app is loading something in the background. That place is not the same for both images, because one of them is obviously higher that the other, so I want to set an autolayout constraint that allows me to put that activity indicator at different heights, depends on if the app is running in an iPhone 5 or not.

    Without Autolayout, I'd set the frame.origin.y of the view to 300 (for example), and then in the viewDidLoad method of the ViewController, I'd ask if the app is running in an iPhone 5, so I'd change the value to, for example, 350. I have no idea how to do this using Autolayout and I think it has to be pretty simple.