1

I create a UIButton programmatically and add it to a view like this :

self.button = [[UIButton alloc] initWithFrame:CGRectMake(20, 20, 100, 30)];
[self.button setTitle:@"Test" forState:UIControlStateNormal];
self.button.translatesAutoresizingMaskIntoConstraints = YES;
[myView addSubview:self.button];

The button appears correctly, and it doesn't use its intrinsic size (which is correct because translatesAutoresizingMaskIntoConstraints is on). However, when i print out myView.constraints, i do not see any constraint regarding the button. By definition, when translatesAutoresizingMaskIntoConstraints is on, constraints will be automatically generated and added to the superview, which is myView in this case.

So why no constraints are generated here ? And why the layout system still knows how to layout the button on screen ?

********Updated: i think i know the reason. When a UIView doesn't have any constraint attached to it, Layout system will not come into place. It will uses the view's frame. In this case, when we turn on translatesAutoresizingMaskIntoConstraints, the button's intrinsic constraints are not generated, hence the button does not have any constraint. So the frame will be used. All UIView created from code will have translatesAutoresizingMaskIntoConstraints default to YES, so no constraint is automatically generated for the view. The frame will be use. That makes perfect sense for backward compatibility.

namanhams
  • 546
  • 3
  • 10

1 Answers1

2

The docs describe its behavior as follows:

If translatesAutoresizingMaskIntoConstraints = YES, the view’s superview looks at the view’s autoresizing mask, produces constraints that implement it, and adds those constraints to itself (the superview).

Based on this description, it is expected to be able to look in the ‑[UIView constraints] array to find the translated constraints, but the generated constraints are not added there When you create view programatically (If view is added in nib then only we will get expected behaviour).

After some careful exploration with the debugger, I determined that the constraints are generated on demand during layout by the private method ‑[UIView(UIConstraintBasedLayout) _constraintsEquivalentToAutoresizingMask].

To View that Constraints create a Category of UIView

@interface UIView(TestConstriants)

- (NSArray *)_constraintsEquivalentToAutoresizingMask;

@end

Import this category to your ViewController class #import "UIView+TestConstriants.h"

Call This lines of code ofter adding self.button to view :

NSLog(@"constraints: %@", [self.button _constraintsEquivalentToAutoresizingMask]);

The above logs the constraints equivalent to autoResize mask. Try testing by setting autoresizingMask to different values you will get corresponding equivalent constraints.

Yatheesha
  • 10,412
  • 5
  • 42
  • 45
  • Actually no constraints are generated for the button. See my first post update for explanation. – namanhams Jun 25 '14 at 09:40
  • But if View is auto layout enabled , it always generate constraints for its subviews. – Yatheesha Jun 25 '14 at 13:43
  • it doesn't. Only if the view already has a constraint (either by adding to it, or if the view has intrinsic size and translatesAutoresizingMaskIntoConstraints = NO), otherwise no constraint is generated for it, disregard of its superview. It's for backward compatibility. Suppose you use a non-autolayout library which has a custom UIView in your project. There will be no constraint generated for that view, unless you explicitly want so. – namanhams Jun 25 '14 at 14:54