Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to selectively override layout contraints in Interface Builder?

I'm attempting to adjust the size of a UIImageView dependent on whether the device is an iPhone 5 (tall screen) or an earlier iPhone version (shorter screen). Below is my code. However when I run the app these instructions are ignored. I suspect the problem is caused by auto layout constraints. If I turn those constraints off the image is resized but that messes up the rest of my layout. Is there anyway to selectively override auto layout rather than turning it off?

CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568) {

    // code for 4-inch screen
    avatarImage.frame = CGRectMake(43, 372, 75, 75);



} else {

    // code for 3.5-inch screen
    avatarImage.frame = CGRectMake(43, 372, 50, 50);

}

EDIT

Below is an image of the problem I am trying to solve. I want the avatar image to resize proportionally until it fits in the smaller view. And I want to programmatically move the text field up and to the right of the label.

enter image description here

enter image description here

like image 932
hughesdan Avatar asked Jan 05 '13 20:01

hughesdan


People also ask

What are two properties that auto layout constraints control on a UIView?

Auto Layout defines margins for each view. These margins describe the preferred spacing between the edge of the view and its subviews. You can access the view's margins using either the layoutMargins or layoutMarginsGuide property.

Why do we use Autolayout?

Autolayout is a feature in Figma that allows designers to create responsive designs. With autolayout, designers can specify how objects should resize and reposition themselves based on the size of the frame. Autolayout is especially useful for designing interfaces that need to work on multiple screen sizes.

What are auto layout constraints?

Auto Layout constraints allow us to create views that dynamically adjust to different size classes and positions. The constraints will make sure that your views adjust to any size changes without having to manually update frames or positions.


2 Answers

One way to do this would be to programmatically alter your constraints. You can do this by:

  1. Create height and width constraints for your imageview by selecting the image view, and then in Xcode 5, clicking on the m button:

    enter image description here

    Or, in the prior versions of Xcode, by clicking on the center button:

    create constraints

  2. Make sure to change the other, secondary, constraints work permit the resizing of the imageview. For example, if you have a label to the right of this thumbnail image, you want to make sure that it is set up so the width of the label will adjust as the size of the image changes. Bottom line, you want to make sure you don't have constraint conflicts when the app runs, because if you do have some conflicts, you may get a debugging message about having to break a constraint to make the app work, or worse, that the constraints are not satisfiable.

  3. Create IBOutlet references for your new height and width constraints. The easiest way is to show the assistant editor (so your associated .h files show up while you're manipulating your storyboard) and then control-drag from the constraint to the .h file:

    create IBOutlets

  4. Then in your code, you can alter your constraints:

    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    
    if (screenBounds.size.height >= 568) {
        self.widthConstraint.constant = 75;
        self.heightConstraint.constant = 75;
    } else {
        self.widthConstraint.constant = 50;
        self.heightConstraint.constant = 50;
    }
    
like image 195
Rob Avatar answered Oct 17 '22 01:10

Rob


In this case, I would say that instead of specifying a height, you probably want to constrain the top space to superview and bottom space to superview. When the superview's height changes, the height of the subview will grow accordingly.

Moving the textView up and to the right instead of being below will be more challenging. You might be able to achieve that effect with different constraint priorities, but you'll probably end up infuriated. This sounds like a non-trivial situation for which you'd be better off updating the constraints programmatically at runtime.

@Rob has offered up a decent point, which is that you can plug constraints into IBOutlets and modify or delete them programmatically later. Perhaps that approach will bear fruit in this case too.

like image 26
ipmcc Avatar answered Oct 16 '22 23:10

ipmcc