Houman Houman - 6 months ago 24
iOS Question

Can constraintsWithVisualFormat be used with dynamically generated views?

I have a list of tags in my model. I would like to add them as label inside a

tagView
UIView as subviews.

NSMutableArray *list = [NSMutableArray new];
for (long i=0; i<_tagView.subviews.count; i++) {
UILabel *tagLabel = _tagView.subviews[i];
[tagLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[list addObject:tagLabel];
}

// Create the views and metrics dictionaries
NSDictionary *metrics = @{@"height":@25.0};
NSDictionary *views = NSDictionaryOfVariableBindings(list[0], list[1], list[2]);

// This is experimental as I assume there are three subviews in that.

[_tagView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[list[0]]-[list[1]]-[list[2]]-|" options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:metrics views:views]];


Is this doable or do I have to take a different direction?

I forgot to add the error message I am getting:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse constraint format:
list is not a key in the views dictionary.
|-[list[0]]-[list[1]]-[list[2]]-|
^'


UPDATE:

keys seem to be fine.
enter image description here

Answer

You should create your own dictionary, so the names can be added that don't have the extra brackets that you're getting now. Names like "list[0]" seem to be confusing the parser.

 NSMutableDictionary *views = [NSMutableDictionary new];
 NSMutableArray *list = [NSMutableArray new];
        for (long i=0; i<_tagView.subviews.count; i++) {
            UILabel *tagLabel = _tagView.subviews[i];
            [tagLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
            [list addObject:tagLabel];
            [views setObject:tagLabel forKey:[NSString stringWithFormat:@"label%ld", i]];
        }

        NSDictionary *metrics = @{@"height":@25.0};

        [_tagView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[label1]-[label2]-[label3]-|" options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:metrics views:views]];
Comments