Updating existing constraints does not work, wrong use of .active property?

风流意气都作罢 提交于 2019-12-22 18:48:21

问题


I have a storyboard that contains :

  • A "tab bar" on the left with 5 tabs
  • A container on the right side of the tab bar that contains 6 image views that share the same space so it looks like this :

Each image view is configured to occupy 1/3 of the container's width and 1/2 of its height.

However, different ratios can be provided at runtime (from a JSON file) so that for example, the 1st image view's height become 70% of its container's height and 50% of its width (therefore, the 2nd and 3rd image views widths occupy 25% of the container's width and the 4th image view, 2nd line column 1 has a height of 30% of the image view).

To do so here is what I tried :

-create 2 arrays of outlets (width and height constraints from my image views) :

// Height constraints
@IBOutlet var heightConstraints: [NSLayoutConstraint]!

// Width constraints
@IBOutlet var widthConstraints: [NSLayoutConstraint]!

-create an outlet for the container of the image views

// Drawings - Container
@IBOutlet weak var drawingView: UIView!

-create stored properties to update my constraints (these are not outlets)

// Drawing height property
var drawingHeightConstraint: NSLayoutConstraint?

// Drawing width property
var drawingWidthConstraint: NSLayoutConstraint?

And here comes the job : I've overridden updateViewConstraints(), is this a mistake ? It seemed the best place to update constraint but I saw people use ViewWillAppear... This method is called every time I click on a tab (and then load new drawings with new ratios)

public override func updateViewConstraints() {
    super.updateViewConstraints()

    // Activate default height and width constraints
    PapooHomePageViewController.activateConstraint(constraints: heightConstraints)
    PapooHomePageViewController.activateConstraint(constraints: widthConstraints)

    // Deactivate temporarily created new height and width constraints
    drawingHeightConstraint?.active = false
    drawingWidthConstraint?.active = false

    // Display drawings
    let drawingElements:[(String, Double, Double)] = papooBrain.getDrawings(forSection: currentSection)
    for (index, (drawing, heightRatio, widthRatio)) in drawingElements.enumerate() {
        drawingViews[index].image = UIImage(named: drawing)

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

        if widthRatio != Double(widthConstraints[index].multiplier) {
            widthConstraints[index].active = false
            drawingWidthConstraint = NSLayoutConstraint(item: drawingViews[index], attribute: .Width, relatedBy: .Equal, toItem: drawingView, attribute: .Width, multiplier: CGFloat(widthRatio), constant: 0)
            drawingWidthConstraint!.active = true
        }

    }

    // Which one should I or should i NOT call, in what order ?
    drawingView.setNeedsUpdateConstraints()
    drawingView.setNeedsLayout()
    drawingView.layoutIfNeeded()
}

-Here is the code of the little helper to activate my constraints. NOTE: This my be a problem. I try to activate a constraint previously deactivated (it comes from my array of outlets) but I don't want it to be duplicated

class func activateConstraint(constraints constraints: [NSLayoutConstraint]) {
    for constraint in constraints {
        constraint.active = true
    }
}

-Finally, here is a piece of my JSON so you see what I parse...

"drawings": [
    {
        "image": "01-01-drawing.png",
            "height-ratio": "0.5",
            "width-ratio": "0.33",
         etc.

The problem(s)

  • If I change my configuration file (json) to say "Okay, image view 1's height ratio is O.7 and so image view 4's height ratio is 0.3" : I have conflicting constraints (it seems that after all, the "active" property did not deactivate properly my constraint

So when I am debugging, I see all my constraints of width and height getting duplicated, causing a nightmare.

  • The same happens for the height etc.

Many questions here

  • Did I use correctly (in terms of lifecycle etc.) updateViewConstraints() ? Is this good to call the super at the beginning ?

  • What is the correct use of setNeedsLayout, layoutIfNeeded, setNeedsUpdateConstraints...

  • When I set an outlet NSLayoutConstraint's active property to false. Then active = true afterwards, did it get the correct reference to my default height/width from the storyboard ?

Thank you for reading

来源:https://stackoverflow.com/questions/36058648/updating-existing-constraints-does-not-work-wrong-use-of-active-property

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!