Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify constraint programmatically Swift

I have the following view controller in my storyboard :

storyboard_mainVC

It will always have 6 image views that are, by default, equal in widths and heights. Each image view is constrained to the superview with : "equal heights" and a multiplier of 1/2.

However, before I load images inside, I read a property that gives me the desired height for an image (width will never be modified).

So my interface (at runtime) can look like this :

second_interface

I think I need to modify the multiplier constant but it's read-only.

I saw posts saying that we can update the constant property of the constraint but it's in points, I need it to work on every device.

Now what would you recommend ? Should I remove the constraint and add a new one ? If I don't remove it and try to apply a new height constraint, will it be removed automatically for me ?

Do I have to use pods like snapkit to do the job ?

Thanks for your help.

EDIT

Here is the code I tried, but did not succeeded :

        for (index, (drawing, ratio)) in drawingElements.enumerate() {
            drawingViews[index].image = UIImage(named: drawing)
            // update height constraint if ratio is different than defaut ratio of 1/2
            if ratio != 0.5 {
                heightConstraints[index].active = false
                let newHeightConstraint = NSLayoutConstraint(item: drawingViews[index], attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.Height, multiplier: ratio, constant: 0)
                drawingViews[index].addConstraint(newHeightConstraint)
                self.view.layoutIfNeeded()
            }
        }

Am I doing it wrong ? I am unsure about the new height constraint though

like image 504
H4Hugo Avatar asked Mar 14 '16 10:03

H4Hugo


People also ask

How do I change a constraint in Swift?

Select the height constraint from the Interface builder and take an outlet of it. So, when you want to change the height of the view you can use the below code. Method updateConstraints() is an instance method of UIView . It is helpful when you are setting the constraints programmatically.

How do I give a constraint to button programmatically in Swift?

Add the button in the view, give it constraints and as you are using constraints, you can skip the button. frame and add widthAnchor and heightAnchor . At last activate them and keep translatesAutoresizingMaskIntoConstraints as false . Also, it will be better if you can add proper names.

How do I change constraints in Xcode?

Clicking the Edit button in any of the constraints brings up a popover where you can change the constraint's relationship, constant, priority, or multiplier. To make additional changes, double-click the constraint to select it and open it in the Attribute inspector.


2 Answers

So this is the way I achieved this :

  • Create a constraint programmatically (height in my case) :

    // Drawing height property
    var drawingHeightConstraint: NSLayoutConstraint?
    
  • Deactivate old constraint and set the new one if needed

Note: heightContraints is an array of NSLayoutConstraint which contains my outlets

        for (index, (drawing, ratio)) in drawingElements.enumerate() {
        drawingViews[index].image = UIImage(named: drawing)

        // update height constraint if ratio is different than defaut ratio of 1/2
        if ratio != 0.5 {
            heightConstraints[index].active = false
            drawingHeightConstraint = NSLayoutConstraint(item: drawingViews[index], attribute: .Height, relatedBy: .Equal, toItem: drawingView, attribute: .Height, multiplier: CGFloat(ratio), constant: 0)
            drawingHeightConstraint!.active = true
        }

    }
  • Call layoutIfNeeded() right after (note: not sure when to call it)
like image 95
H4Hugo Avatar answered Oct 04 '22 20:10

H4Hugo


The constraints constants are related to the content of the constrained element. That why you're getting such screen. The easiest way - create image with clear color and set it by default. After downloading completed just set new image for your imageView

Or you can set IBOutlet for your height constraint - and change it value for different situations i.e.

if(download.completed)
ibHeightOutlet.constant = imageView.frame.size.height;
else
ibHeightOutlet.constant = initialImageViewHeght.frame.size.height;
like image 22
Karaban Avatar answered Oct 04 '22 20:10

Karaban