Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autolayout programmatically on a subview of a subclassed UIView

I have subclassed UIView to make a custom groupView I use to add a few things to my layout in a simple way. This groupView includes a UILabel which is used as a heading and a UIView that draws a roundRect on it's CALayer with a background color. Think UITableView's sections. I add this groupView to the storyboard by dropping a UIView and changing it's class to my subclass. All works well, I set the heading via the User defined runtime attributes in Xcode. All works great, I add UILabels to this view on the storyboard and it creates the heading label and roundrect when it runs.

structure of my groupView:

  1. groupView: (UIView)clipToBounds:NO;
    • heading: (UILabel) positioned above the groupView.
    • contentView:(UIView) creates the roundRect and color via CALayer, should be same size as the groupView.

So what's the problem? Well, dealing with autolayout is a pain to begin with, but for this subclassed UIView to work I need to set the contentView constraints programmatically. I can't figure out the syntax of this auto layout ASCII format string. Currently I have:

 _contentView = [[UIView alloc]initWithFrame:self.bounds];

    _contentView.layer.cornerRadius = 5.0f;
    _contentView.layer.masksToBounds=YES;
    _contentView.backgroundColor=_backgroundColor;
    _contentView.layer.borderWidth=_borderWidth;
    _contentView.layer.borderColor=_borderColor.CGColor;
    [self insertSubview:_contentView atIndex:0];
    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(self,_contentView);
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"[self]-0-[_contentView]-0-[self]" options:0 metrics:nil views:viewsDictionary];

    for (NSLayoutConstraint *constraint in constraints) {
        [_contentView addConstraint:constraint];
    }

Which crashes with: * 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: view:>'

I tried this first and it still didn't work:

    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_contentView);
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-0-[_contentView]-0-|" options:0 metrics:nil views:viewsDictionary];

Which crashes with: * 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: view:>'

RANT: Somehow this AutoLayout is suppose to save us work, but I do not see how the benefits out weight the overhead right now. Why on earth did they move from using references and methods or even type defs to this archaic format string? How much easier would it be to do: [_contentView constraint:NSLayoutFormatAlignLeading toView:self withDistance:0.0f]; OR something similar? I would so much rather deal with springs and struts at this point.

Any help understanding, or showing me the syntax to constrain the contentView to the size of self would be helpful.

like image 463
brucemartin Avatar asked Nov 20 '12 16:11

brucemartin


1 Answers

The error tells you what you need to know:

Does the constraint reference something from outside the subtree of the view?

Yes it does. It references its superview.

These constraints you are making need to be applied to the superview, in this case the groupView.

like image 95
jackslash Avatar answered Oct 17 '22 19:10

jackslash