Search code examples
iosnslayoutconstraintlayoutsubviewsios-autolayout

How to update constraint after layout subviews?


I know that rendering a view has the following 3 steps in this order:

  1. updating constraints
  2. layout views (here is where we get calculation of frames)
  3. display

Now my question if I modify the custom buttons height, and that button has constraint with surrounding views, how can I update that constraints and avoid to overlap with views? You can see commented line, non of them works.

class DynamicHeightButton: UIButton {

    override func layoutSubviews() {
        super.layoutSubviews()

        let size = (self.titleForState(UIControlState.Normal)! as NSString).boundingRectWithSize(CGSizeMake(self.bounds.size.width, CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName : UIFont.systemFontOfSize(17)], context: nil)
        self.bounds.size.height = size.height + 8

        //viewController!.view.setNeedsUpdateConstraints()
        //self.setNeedsUpdateConstraints()
        //self.setNeedsLayout()
    }
}

Solution

  • When using Autolayout view's frame shouldn't be set. Instead of it constraints should be adjusted, usually the 'constant' property.

    In my case, I am changing the height of a view and in the process breaking a constraint.

    I have added 3 lines to my custom class:

    @IBOutlet weak var height: NSLayoutConstraint
    
    self.bounds.size.height = size.height + 8
    height.constant = size.height + 8