1
votes

i am struggling with an UIScrollView in iOS6 using auto layout. What i am trying to do is setting up a scrollview holding a number of subviews (UIViews). Those subviews are created dynamically in a loop. Now i would like to add my contraints, so that it is working with auto layout.

In viewDidLoad I got this code:

scrollView.pagingEnabled = YES;
CGRect selfBounds = self.view.bounds;
CGFloat width = CGRectGetWidth(self.view.bounds);
CGFloat height = CGRectGetHeight(self.view.bounds);
NSMutableString *constraintBuilding = [NSMutableString stringWithFormat:@"|"];

NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor blueColor], nil];
for (int i = 0; i < colors.count; i++) {
    CGFloat offset = width * i;
    UIView* view1 = [[UIView alloc] initWithFrame:CGRectOffset(selfBounds, offset, 0)];
    [view1 setTranslatesAutoresizingMaskIntoConstraints:NO];
    [view1 setBackgroundColor:[colors objectAtIndex:i]];
    [scrollView addSubview:view1];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view1(height)]|" options:0 metrics:@{@"height":@(height)} views:NSDictionaryOfVariableBindings(view1)]];
    [constraintBuilding appendString:[NSString stringWithFormat:@"[view%i(width)]",i+1]];
}

NSMutableArray *views = [[NSMutableArray alloc] init];

for (int j = 0; j < scrollView.subviews.count; j++) {
    if (![[scrollView.subviews objectAtIndex:j] isKindOfClass:[UIImageView class]]) {
        [views addObject:[scrollView.subviews objectAtIndex:j]];
    }
}


[constraintBuilding appendString:@"|"];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:constraintBuilding options:0 metrics:@{@"width":@(width*colors.count)} views:NSDictionaryOfVariableBindings(views)]];

the looping works just fine, but i'll get an error on the last line

[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:constraintBuilding options:0 metrics:@{@"width":@(width*colors.count)} views:NSDictionaryOfVariableBindings(views)]];

constraintBuilding says " |[view1(width)][view2(width)][view3(width)]| " Actually i dont have a view2 and view 3 but i dont know how to set up the contraint?!

That is the exception:

'NSInvalidArgumentException', reason: 'Unable to parse constraint format: 

view1 is not a key in the views dictionary. |[view1(width)][view2(width)][view3(width)]| ^'

For testing i have 3 objects in my colors array, but later this number will change dynamically.

Thanks for your help!

Chris

EDIT:

one more thing. I read this article and it worked just fine. but unfortunately it is not in a loop with a dynamic number of views. :(

AND

I read this article from apple. but still i couldnt find my answer.

2
Did you get this working, I have a similar issue creating constraints for dynamic amount of viewsStuartM

2 Answers

2
votes

I think there have you result. just testing, and flow.

use it FOR loop.

http://www.apeth.com/iOSBook/ch20.html

1
votes

NSDictionaryOfVariableBindings(views)

On this line views is an array. This will create a dictionary with a single entry, with a key of views as an object of your array.

The views dictionary passed into the visual format method must have an entry for each view variable used in the VFL string.

Instead of building up a mutable array of your views, build up a mutable dictionary, adding in each loop the single-view dictionary made when you create the vertical constraints.

You can then use this completed dictionary in the final visual format method.