简体   繁体   中英

Constraints on subclassed UIView throw off programmatically created UILabel position

I have a subclassed UIView that creates a UILabel programmatically but it does not do well when the UIView is given constraints...

What I am trying to do:

在此处输入图片说明

The label should be positioned on top of the view.

My subclassed UIView will creates a UILabel like this:

//In interface
@property(nonatomic, strong) UILabel *myLabel;

//in implementation
self.myLabel = [[UILabel alloc] initWithFrame:[self bounds]];
/*
set properties
*/
[self.superview addSubview:[self myLabel]];

This provides the desired behavior with the label having the same size and position as the subclassed UIView. But when I add constraints to the UIView in the storyboard, the UILabel is rendered in the wrong place.

Here's what's happening: (UIView shaded yellow, UILabel shaded teal) 在此处输入图片说明

I have tried changing

[self.superview addSubview:[self myLabel]];

to

[self addSubview:[self myLabel]];

but that does not work either.

How can I make the UILabel render on top of the UIView?

If you add the label in code, you should also add constraints to it in code. The trick with constraints is to remember to add the constraint to the ( hierarchically )topmost view of the 2 views linked by the constraint, or to the first common parent view.

Note that mixing IB auto layout and coded constraints might be quite the headache. I've ran into cases where I've had to set UIView.translatesAutoResizingMasksIntoConstraints to NO for it to work properly.

I just tried this after adding the UILabel to the UIView:

NSLayoutConstraint *xPosConstraint = [NSLayoutConstraint constraintWithItem:self
                                                                  attribute:NSLayoutAttributeCenterX
                                                                  relatedBy:NSLayoutRelationEqual
                                                                     toItem:self.myLabel
                                                                  attribute:NSLayoutAttributeCenterX
                                                                 multiplier:1.0
                                                                   constant:0];

[self addConstraint:xPosConstraint];

Which caused a crash...

The view hierarchy is not prepared for the constraint: 
<NSLayoutConstraint:0x7fe0f0f750d0 MyUIView:0x7fe0f0f55b90.centerX == UILabel:0x7fe0f0f71810.centerX>
When added to a view, the constraint's items must be descendants of that view 
(or the view itself). This will crash if the constraint needs to be resolved before 
the view hierarchy is assembled. 
Break on -[UIView _viewHierarchyUnpreparedForConstraint:] to debug.
2014-12-24 13:26:40.319 circle[28901:2153934] View hierarchy unprepared for constraint.
Constraint: <NSLayoutConstraint:0x7fe0f0f750d0 MyUIView:0x7fe0f0f55b90.centerX == UILabel:0x7fe0f0f71810'0%'.centerX>
Container hierarchy: < MyUIView: 0x7fe0f0f55b90; 
frame = (200 28; 200 200); autoresize = RM+BM; 
layer = <CALayer: 0x7fe0f0f54000>>
View not found in container hierarchy: <UILabel: 0x7fe0f0f71810; 
frame = (200 28; 200 200); text = '0%'; userInteractionEnabled = NO; 
layer = <_UILabelLayer: 0x7fe0f0f71970>>
That view's superview: <UIView: 0x7fe0f0f56760; frame = (0 0; 375 667); 
autoresize = W+H; layer = <CALayer: 0x7fe0f0f56a30>>

and

2014-12-24 13:26:40.334 circle[28901:2153934] *** Terminating app due to uncaught exception
'NSGenericException', reason: 
'Unable to install constraint on view.  
Does the constraint reference something from outside the subtree of the view?  
That's illegal. 
constraint:<NSLayoutConstraint:0x7fe0f0f750d0 
MyUIView:0x7fe0f0f55b90.centerX == UILabel:0x7fe0f0f71810'0%'.centerX> 
view:< MyUIView: 0x7fe0f0f55b90; 
frame = (200 28; 200 200); autoresize = RM+BM; layer = <CALayer: 0x7fe0f0f54000>>'

Also, adding the constraint to the superview like this:

[self.superview addConstraint:xPosConstraint];

...causes the debugger to break the constraint because it can't be satisfied.

Beginning to hate auto layout...

****Edit**** Fixed it. Gah. Just needed to add this:

[self.myLabel setTranslatesAutoresizingMaskIntoConstraints:NO];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM