问题
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