RPK
RPK

Reputation: 1994

AutoLayout inside of an AutoResizingView

I am trying to create a custom inputView for a UITextView. I have a subclass of a UIView that I am working in, and I'm trying to add UI elements to it. The view itself is set to self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; so that the system will fill the view to the size of what the inputView should be.

I can't seem to get AutoLayout constraints to work inside of this view. No matter how many different things I try, I always have conflicting constraints.

Is it possible to use AutoLayout inside of an autoresizing view?

Here is some sample code of what I'm doing:

UILabel *label = [[UILabel alloc] init];
label.text = @"Test Label";
label.textAlignment = NSTextAlignmentCenter;

[self addSubview:label];

NSArray *labelHorizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-8.0-[label]-8.0-|" options:0 metrics:nil views:@{ @"label" : label }];

NSArray *labelVerticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-8.0-[label]" options:0 metrics:nil views:@{ @"label" : label }];

NSMutableArray *constraintsArray = [NSMutableArray array];
[constraintsArray addObjectsFromArray:labelHorizontalConstraints];
[constraintsArray addObjectsFromArray:labelVerticalConstraints];

[self addConstraints:constraintsArray];

And this is the kind of errors that I'm getting:

2015-07-21 05:56:38.804 InputView[880:22401] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x79175910 UIInputSetHostView:0x79175640.width == UIInputSetContainerView:0x79174ff0.width>",
    "<NSLayoutConstraint:0x78f8f240 'UIView-Encapsulated-Layout-Width' H:[UIInputSetContainerView:0x79174ff0(768)]>",
    "<NSLayoutConstraint:0x7932ffa0 H:|-(8)-[UILabel:0x79364df0'Test Label']   (Names: '|':TestInputView:0x79364f10 )>",
    "<NSLayoutConstraint:0x7932d1a0 H:[UILabel:0x79364df0'Test Label']-(8)-|   (Names: '|':TestInputView:0x79364f10 )>",
    "<NSLayoutConstraint:0x793611b0 TestInputView:0x79364f10.right == UIInputSetHostView:0x79175640.right>",
    "<NSLayoutConstraint:0x79361180 H:|-(0)-[TestInputView:0x79364f10](LTR)   (Names: '|':UIInputSetHostView:0x79175640 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x79362920 h=--& v=--& UILabel:0x79364df0'Test Label'.midX ==>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7932d1a0 H:[UILabel:0x79364df0'Test Label']-(8)-|   (Names: '|':TestInputView:0x79364f10 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2015-07-21 05:56:38.805 InputView[880:22401] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7932ffa0 H:|-(8)-[UILabel:0x79364df0'Test Label']   (Names: '|':TestInputView:0x79364f10 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x79362920 h=--& v=--& UILabel:0x79364df0'Test Label'.midX ==>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7932ffa0 H:|-(8)-[UILabel:0x79364df0'Test Label']   (Names: '|':TestInputView:0x79364f10 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2015-07-21 05:56:38.812 InputView[880:22401] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7932e7e0 V:|-(8)-[UILabel:0x79364df0'Test Label']   (Names: '|':TestInputView:0x79364f10 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x79362980 h=--& v=--& UILabel:0x79364df0'Test Label'.midY ==>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7932e7e0 V:|-(8)-[UILabel:0x79364df0'Test Label']   (Names: '|':TestInputView:0x79364f10 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

Any help would be appreciated. Thanks.

Upvotes: 1

Views: 548

Answers (1)

Max MacLeod
Max MacLeod

Reputation: 26652

Set translatesAutoresizingMaskIntoConstraints for label to false:

label.setTranslatesAutoresizingMaskIntoConstraints(false)

See Adopting Auto Layout:

For views that are aware of Auto Layout, in most circumstances you want translatesAutoresizingMaskIntoConstraints to be NO. The reason is that the constraints generated by translating the autoresizing mask are already sufficient to completely specify the frame of a view given its superview’s frame, which is generally too much. For example, this translation would prevent a button from automatically assuming its optimal width when its title is changed.

From experience, forgetting to set that flag on programmatically created views has to be the number one cause of constraint exceptions.

To answer your question regarding mixing Auto Layout and Auto Resizing; both can be freely mixed and matched. However it's not correct to say that your project is using both. If you have Auto Layout enabled, that applies to the entire project. Views may still be configured using Auto Resizing, but what is actually happening is that those specifications are being translated into Auto Layout constraints. The problem above is that you have the Auto Resizing view - label - with it's translated constraints, conflicting with additional Auto Layout constraints that you specify.

Upvotes: 1

Related Questions