TIL by Ed

Writing up things I’ve learnt.

The Mystery of the +requiresConstraintBasedLayout

I use AutoLayout. I read about AutoLayout. I’ve also watched a couple of talks on AutoLayout. In exploring AutoLayout, I’ve come across this odd class method requiresConstraintBasedLayout on UIView. After using AutoLayout extensively on 

  • 3+ projects,
  • 100+ UIViews,
  • 100,000+ constraints,

I’ve never had to use this method. According to the documentation for requiresConstraintBasedLayout

Returns whether the receiver depends on the constraint-based layout system.

Custom views should override this to return YES if they can not layout correctly using autoresizing.

Wait!! I was using constraints all this time, but I never had to override this class method. This bugged me. Why was all my view laying out fine even though I didn’t override this method on my custom UIView subclasses? There was an objc.io article that advised that you declare your view’s dependency on AutoLayout explicitly by overriding this when creating UIView subclasses that uses constraints. My views were dependent on AutoLayout and ONLY used constraints, but it worked fine still without needing to do this step. I also bought up the question at my local cocoaheads meetup during a AutoLayout talk, but came up empty unfortunately. All explanations of this class method made sense. But the fact that AutoLayout still worked for me regardless of me needing to override this method, suggested that some part of the puzzle was missing. There was something else that was missing from the documentation that would fill the gap in my understanding. A clearer answer finally came after my @somekindaofmica decided to look at the UIView header (not the documentation). The header file had this to say

constraint-based layout engages lazily when someone tries to use it (e.g., adds a constraint to a view).  If you do all of your constraint set up in -updateConstraints, you might never even receive updateConstraints if no one makes a constraint.  To fix this chicken and egg problem, override this method to return YES if your view needs the window to use constraint-based layout.

Wow! That should have really been included in the documentation. The purpose of this class method is totally making sense now. I don’t usually set up all constraints inside -updateConstraints. Even if I did have a UIView subclass that sets up ALL of its constraints inside -updateConstraint, I would usually have another UIView subclass somewhere else in the view hierarchy that would “engage” AutoLayout by adding constraints outside of -updateConstraints. This explains why my UIView’s have laid out correctly using constraints when I haven’’t been overriding this class method.

TL;DR

If you set up all your constraints in -updateConstraints in your UIView subclass, make sure you override +requiresConstraintBasedLayout. I’ve attached a sample project to demonstrate this. You can see the behaviour by (un)commenting the overrided +requiresConstraintBasedLayout class method. https://github.com/ehuynh/RequiresConstraintBasedLayoutExample

Comments