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.

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.


The | character represents the superview in the visual format language, so I think you want:

@"|-0-[_contentView]-0-|"

and then you need to add the constraint to self instead of the contentView, as you need to add it to a view which can see all of the players involved.

Here is the reference for the visual language: https://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AutolayoutPG/Articles/formatLanguage.html#//apple_ref/doc/uid/TP40010853-CH3-SW1

You can also avoid the visual format entirely by using:

+(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c

try check the constrints , whether they are right add to the view

eg:

UIView *yellowView = [[UIView alloc] init];
yellowView.backgroundColor = [UIColor yellowColor];
yellowView.translatesAutoresizingMaskIntoConstraints = false;
[self.view addSubview:yellowView];

//ios 9 last
NSLayoutConstraint *heightAnchor = [yellowView.heightAnchor constraintEqualToAnchor:self.purView.heightAnchor];
// addConstraints
[self.view  addConstraints:@[heightAnchor]];
[self.view setNeedsLayout];

if add heightAnchor to yellowView like follow . it will show the error

[yellowView addConstraints:@[heightAnchor]];


Need Your Help

Query with subquery needs to return all rows from original query (even when subquery comes back empty)

mysql subquery

I am trying to write an SQL query that returns the maximum value scored on a test per employee, with each test in its own column.

Sitecore 6.5 rev. 120247 media urls adding a leading slash

url media upgrade sitecore

To be able to use Edgecast CDN, we had to write a custom media provider which worked well with before the site was upgraded from 6.5 rev 111230 to 120427. After the upgrade, none of the images show...